4,554
edits
| No edit summary | No edit summary | ||
| (686 intermediate revisions by 2 users not shown) | |||
| Line 1: | Line 1: | ||
| $(document).ready(function () { | |||
| document. |   // Global variables | ||
|   var cards = $(".card"); | |||
|   var showArticleWrapper = $("#show-article-wrapper"); | |||
|   var areFiltersActive = false; | |||
|      //  |   // Make header-box in Home clickable | ||
|      cards. |   $(".head-box").click(function () { | ||
|          card. |     window.location.href = "/Main_Page"; // Redirects to the home page | ||
|              //  |   }); | ||
|              console.log( | |||
|   // Loop through each card to format related articles | |||
|   cards.each(function () { | |||
|     // Check if the card has related articles | |||
|     var relatedArticles = $(this).find(".related-articles"); | |||
|      if (relatedArticles.length > 0) { | |||
|       // Get all the related article elements | |||
|       var relatedArticleElements = relatedArticles.find(".related-article"); | |||
|       // Create an array to store unique related articles | |||
|       var uniqueArticles = []; | |||
|       // Loop through each related article element | |||
|       relatedArticleElements.each(function () { | |||
|         // Remove <p> tags from the article | |||
|         $(this).find("p").remove(); | |||
|         // Convert the article HTML to a string | |||
|         var articleHTML = $(this)[0].outerHTML; | |||
|         // Check if the article HTML already exists in the uniqueArticles array | |||
|         if ($.inArray(articleHTML, uniqueArticles) === -1) { | |||
|           // If it doesn't exist, add it to the uniqueArticles array | |||
|           uniqueArticles.push(articleHTML); | |||
|         } | |||
|       }); | |||
|       // Clear the content of the related articles container | |||
|       relatedArticles.empty(); | |||
|       // Append the unique related articles back to the container | |||
|       relatedArticles.append(uniqueArticles.join("")); | |||
|     } | |||
|   }); | |||
|   // Utility Functions | |||
|   function sortChronologically() { | |||
|     var cards = $(".list-container .card").get(); | |||
|     cards.sort(function (a, b) { | |||
|       var numberA = parseInt( | |||
|         $(a).find(".entry-number").text().replace(/\[|\]/g, ""), | |||
|         10 | |||
|       ); | |||
|       var numberB = parseInt( | |||
|         $(b).find(".entry-number").text().replace(/\[|\]/g, ""), | |||
|         10 | |||
|       ); | |||
|       return numberB - numberA; // Descending order | |||
|     }); | |||
|     $.each(cards, function (index, item) { | |||
|       $(".list-container").append(item); | |||
|     }); | |||
|   } | |||
|   function randomizeCards(selector) { | |||
|     var cards = $(selector).get(); | |||
|     var i = cards.length, | |||
|       j, | |||
|       temp; | |||
|     while (--i > 0) { | |||
|       j = Math.floor(Math.random() * (i + 1)); | |||
|       temp = cards[i]; | |||
|       cards[i] = cards[j]; | |||
|       cards[j] = temp; | |||
|     } | |||
|     $.each(cards, function (index, item) { | |||
|       $(selector).parent().append(item); | |||
|     }); | |||
|   } | |||
|   function sortAlphabetically(selector) { | |||
|     var cards = $(selector).get(); | |||
|     cards.sort(function (a, b) { | |||
|       var titleA = $(a).find(".title").text().toUpperCase(); | |||
|       var titleB = $(b).find(".title").text().toUpperCase(); | |||
|       return titleA < titleB ? -1 : titleA > titleB ? 1 : 0; | |||
|     }); | |||
|     $.each(cards, function (index, item) { | |||
|       $(selector).parent().append(item); | |||
|     }); | |||
|   } | |||
|   function updateViews() { | |||
|      // Handle cards in the list view | |||
|     $(".home-chronicle-list div.list-container div.card:not(.event)").each( | |||
|       function () { | |||
|         if (!$(this).closest(".home-chronicle-block").length) { | |||
|           var title = $(this).find(".title").detach(); | |||
|           var images = $(this).find(".images").detach(); | |||
|           // Remove existing .title-images if it exists | |||
|           $(this).find(".title-images").remove(); | |||
|           var titleImagesContainer = $( | |||
|             '<div class="title-images"></div>' | |||
|           ).append(images, title); | |||
|           $(this).find(".people").after(titleImagesContainer); | |||
|         } | |||
|       } | |||
|     ); | |||
|     // Handle cards in the block view | |||
|     $(".home-chronicle-block div.list-container div.card:not(.event)").each( | |||
|       function () { | |||
|         // Remove .title-images container if it exists, re-attach .title and .images to their original places | |||
|         var titleImagesContainer = $(this).find(".title-images"); | |||
|         if (titleImagesContainer.length) { | |||
|           var title = titleImagesContainer.find(".title").detach(); | |||
|           var images = titleImagesContainer.find(".images").detach(); | |||
|           titleImagesContainer.remove(); | |||
|           $(this).find(".people").after(title); | |||
|           $(this).find(".type").after(images); | |||
|         } else { | |||
|           // If .title-images doesn't exist, ensure .images is placed correctly | |||
|           var images = $(this).find(".images").detach(); | |||
|           $(this).find(".type").after(images); | |||
|          } | |||
|       } | |||
|     ); | |||
|   } | |||
|   function processEventCards() { | |||
|     $(".card.event").each(function () { | |||
|       var $card = $(this); | |||
|       var existingContainer = $card.find(".container-people-date"); | |||
|       // Create container if missing | |||
|       if (existingContainer.length === 0) { | |||
|         existingContainer = $('<div class="container-people-date"></div>'); | |||
|         $card.append(existingContainer); // temp placement | |||
|       } | |||
|       // Detach people and date | |||
|       var people = $card.find(".people").detach(); | |||
|       var date = $card.find(".date").detach(); | |||
|       // BLOCK VIEW (gallery) | |||
|       if ($card.closest(".home-chronicle-block").length) { | |||
|         existingContainer.append(people).append(date); | |||
|         // Place container after title | |||
|         if (!existingContainer.is($card.find(".title").next())) { | |||
|           $card.find(".title").after(existingContainer); | |||
|         } | |||
|         // LIST VIEW | |||
|       } else if ($card.closest(".home-chronicle-list").length) { | |||
|         // Only append .people into container | |||
|         existingContainer.empty().append(people); | |||
|         // Place container before title | |||
|         $card.find(".title").before(existingContainer); | |||
|         // Place date after title | |||
|         $card.find(".title").after(date); | |||
|       } | |||
|     }); | |||
|   } | |||
|   if ($("#home").length > 0) { | |||
|     // This code will only run only on the homepage. | |||
|     $(".home-block-view").show(); | |||
|     $(".home-chronicle-block-button, .home-block-view-button").addClass( | |||
|       "active-view-button" | |||
|     ); | |||
|     // Initially hide list view sorting buttons and set the default sorted view for block | |||
|     $( | |||
|       ".home-chronicle-list-button, .home-random-list-button, .home-alphabetical-list-button" | |||
|     ).hide(); | |||
|     sortChronologically(); // Sort the block view chronologically by default | |||
|     updateLastVisibleCard(); | |||
|     updateWidthBlockView(); | |||
|     processEventCards(); | |||
|     updateViews(); | |||
|     $(".home-list-view-button").click(function () { | |||
|       $(".home-list-sorting-buttons").css("display", "flex"); | |||
|       // Switching view classes | |||
|       $(".home-block-view") | |||
|         .removeClass("home-block-view") | |||
|         .addClass("home-list-view"); | |||
|       // Additional class switch | |||
|       $(".home-chronicle-block") | |||
|         .removeClass("home-chronicle-block") | |||
|         .addClass("home-chronicle-list"); | |||
|       // Toggling visibility of buttons | |||
|       $( | |||
|         ".home-chronicle-block-button, .home-random-block-button, .home-alphabetical-block-button" | |||
|       ).hide(); | |||
|       $( | |||
|         ".home-chronicle-list-button, .home-random-list-button, .home-alphabetical-list-button" | |||
|       ).show(); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       // Remove active class from block view button and add to list view button | |||
|       $(".home-block-view-button").removeClass("active-view-button"); | |||
|       $(".home-list-view-button").addClass("active-view-button"); | |||
|       // Conditional checks for transferring the active class from block to list buttons | |||
|       if ($(".home-chronicle-block-button").hasClass("active-view-button")) { | |||
|         $(".home-chronicle-block-button").removeClass("active-view-button"); | |||
|         $(".home-chronicle-list-button").addClass("active-view-button"); | |||
|       } else if ( | |||
|         $(".home-random-block-button").hasClass("active-view-button") | |||
|       ) { | |||
|         $(".home-random-block-button").removeClass("active-view-button"); | |||
|         $(".home-random-list-button").addClass("active-view-button"); | |||
|       } else if ( | |||
|         $(".home-alphabetical-block-button").hasClass("active-view-button") | |||
|       ) { | |||
|         $(".home-alphabetical-block-button").removeClass("active-view-button"); | |||
|         $(".home-alphabetical-list-button").addClass("active-view-button"); | |||
|       } | |||
|     }); | |||
|     $(".home-block-view-button").click(function () { | |||
|       console.log("Block view button clicked."); | |||
|       $(".home-list-sorting-buttons").hide(); // Hide list sorting buttons | |||
|       $(".home-list-view") | |||
|         .removeClass("home-list-view") | |||
|         .addClass("home-block-view"); | |||
|       $(".home-chronicle-list") | |||
|         .removeClass("home-chronicle-list") | |||
|         .addClass("home-chronicle-block"); | |||
|       $( | |||
|         ".home-chronicle-block-button, .home-random-block-button, .home-alphabetical-block-button" | |||
|       ).show(); | |||
|       $( | |||
|         ".home-chronicle-list-button, .home-random-list-button, .home-alphabetical-list-button" | |||
|       ).hide(); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".home-list-view-button").removeClass("active-view-button"); | |||
|       $(".home-block-view-button").addClass("active-view-button"); | |||
|       // Conditional checks for transferring the active class from block to list buttons | |||
|       if ($(".home-chronicle-list-button").hasClass("active-view-button")) { | |||
|         $(".home-chronicle-list-button").removeClass("active-view-button"); | |||
|         $(".home-chronicle-block-button").addClass("active-view-button"); | |||
|       } else if ($(".home-random-list-button").hasClass("active-view-button")) { | |||
|         $(".home-random-list-button").removeClass("active-view-button"); | |||
|         $(".home-random-block-button").addClass("active-view-button"); | |||
|       } else if ( | |||
|         $(".home-alphabetical-list-button").hasClass("active-view-button") | |||
|       ) { | |||
|         $(".home-alphabetical-list-button").removeClass("active-view-button"); | |||
|         $(".home-alphabetical-block-button").addClass("active-view-button"); | |||
|       } | |||
|     }); | |||
|     // BLOCK VIEW SORTING BUTTONS | |||
|     $(".home-chronicle-block-button").click(function () { | |||
|       sortChronologically(); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".home-chronicle-block-button").addClass("active-view-button"); | |||
|       $(".home-random-block-button").removeClass("active-view-button"); | |||
|       $(".home-alphabetical-block-button").removeClass("active-view-button"); | |||
|     }); | |||
|     $(".home-random-block-button").click(function () { | |||
|       randomizeCards(".list-container .card"); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".home-random-block-button").addClass("active-view-button"); | |||
|       $(".home-chronicle-block-button").removeClass("active-view-button"); | |||
|       $(".home-alphabetical-block-button").removeClass("active-view-button"); | |||
|     }); | |||
|     $(".home-alphabetical-block-button").click(function () { | |||
|       sortAlphabetically(".list-container .card"); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".home-alphabetical-block-button").addClass("active-view-button"); | |||
|       $(".home-chronicle-block-button").removeClass("active-view-button"); | |||
|       $(".home-random-block-button").removeClass("active-view-button"); | |||
|     }); | |||
|     // LIST VIEW SORTING BUTTONS | |||
|     $(".home-chronicle-list-button").click(function () { | |||
|       sortChronologically(); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".home-chronicle-list-button").addClass("active-view-button"); | |||
|       $(".home-random-list-button").removeClass("active-view-button"); | |||
|       $(".home-alphabetical-list-button").removeClass("active-view-button"); | |||
|     }); | |||
|     $(".home-random-list-button").click(function () { | |||
|       randomizeCards(".list-container .card"); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".home-random-list-button").addClass("active-view-button"); | |||
|       $(".home-chronicle-list-button").removeClass("active-view-button"); | |||
|       $(".home-alphabetical-list-button").removeClass("active-view-button"); | |||
|     }); | |||
|     $(".home-alphabetical-list-button").click(function () { | |||
|       sortAlphabetically(".list-container .card"); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".home-alphabetical-list-button").addClass("active-view-button"); | |||
|       $(".home-chronicle-list-button").removeClass("active-view-button"); | |||
|       $(".home-random-list-button").removeClass("active-view-button"); | |||
|     }); | |||
|   } else { | |||
|     console.log("NOT HOMEPAGE"); | |||
|     $(".home-list-view").show(); | |||
|     $(".chronicle-list-button, .list-view-button").addClass( | |||
|       "active-view-button" | |||
|     ); | |||
|     // Initialization and Default Settings | |||
|     // Initially hide block view sorting buttons and set the default sorted view for list | |||
|     $( | |||
|       ".chronicle-block-button, .random-block-button, .alphabetical-block-button" | |||
|     ).hide(); | |||
|     sortChronologically(); // Sort the block view chronologically by default | |||
|     updateLastVisibleCard(); | |||
|     updateWidthBlockView(); | |||
|     processEventCards(); | |||
|     updateViews(); | |||
|     $(".list-view-button").click(function () { | |||
|       console.log("List view button clicked."); | |||
|       $(".list-sorting-buttons").css("display", "flex"); | |||
|       $(".block-sorting-buttons").hide(); | |||
|       // Switching view classes | |||
|       $(".home-block-view") | |||
|         .removeClass("home-block-view") | |||
|         .addClass("home-list-view"); | |||
|       // Additional class switch | |||
|       $(".home-chronicle-block") | |||
|         .removeClass("home-chronicle-block") | |||
|         .addClass("home-chronicle-list"); | |||
|       // Toggling visibility of buttons | |||
|       $( | |||
|         ".chronicle-block-button, .random-block-button, .alphabetical-block-button" | |||
|       ).hide(); | |||
|       $( | |||
|         ".chronicle-list-button, .random-list-button, .alphabetical-list-button" | |||
|       ).show(); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       // Remove active class from block view button and add to list view button | |||
|       $(".block-view-button").removeClass("active-view-button"); | |||
|       $(".list-view-button").addClass("active-view-button"); | |||
|       // Conditional checks for transferring the active class from block to list buttons | |||
|       if ($(".chronicle-block-button").hasClass("active-view-button")) { | |||
|         $(".chronicle-block-button").removeClass("active-view-button"); | |||
|         $(".chronicle-list-button").addClass("active-view-button"); | |||
|       } else if ($(".random-block-button").hasClass("active-view-button")) { | |||
|         $(".random-block-button").removeClass("active-view-button"); | |||
|         $(".random-list-button").addClass("active-view-button"); | |||
|       } else if ( | |||
|         $(".alphabetical-block-button").hasClass("active-view-button") | |||
|       ) { | |||
|         $(".alphabetical-block-button").removeClass("active-view-button"); | |||
|         $(".alphabetical-list-button").addClass("active-view-button"); | |||
|       } | |||
|     }); | |||
|     $(".block-view-button").click(function () { | |||
|       console.log("Block view button clicked."); | |||
|       $(".list-sorting-buttons").hide(); // Hide list sorting buttons | |||
|       $(".block-sorting-buttons").css("display", "flex"); | |||
|       $(".home-list-view") | |||
|         .removeClass("home-list-view") | |||
|         .addClass("home-block-view"); | |||
|       $(".home-chronicle-list") | |||
|         .removeClass("home-chronicle-list") | |||
|         .addClass("home-chronicle-block"); | |||
|       $( | |||
|         ".chronicle-block-button, .random-block-button, .alphabetical-block-button" | |||
|       ).show(); | |||
|       $( | |||
|         ".chronicle-list-button, .random-list-button, .alphabetical-list-button" | |||
|       ).hide(); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".list-view-button").removeClass("active-view-button"); | |||
|       $(".block-view-button").addClass("active-view-button"); | |||
|       // Conditional checks for transferring the active class from block to list buttons | |||
|       if ($(".chronicle-list-button").hasClass("active-view-button")) { | |||
|         $(".chronicle-list-button").removeClass("active-view-button"); | |||
|         $(".chronicle-block-button").addClass("active-view-button"); | |||
|       } else if ($(".random-list-button").hasClass("active-view-button")) { | |||
|         $(".random-list-button").removeClass("active-view-button"); | |||
|         $(".random-block-button").addClass("active-view-button"); | |||
|       } else if ( | |||
|         $(".alphabetical-list-button").hasClass("active-view-button") | |||
|       ) { | |||
|         $(".alphabetical-list-button").removeClass("active-view-button"); | |||
|         $(".alphabetical-block-button").addClass("active-view-button"); | |||
|       } | |||
|     }); | |||
|     // BLOCK VIEW SORTING BUTTONS | |||
|     $(".chronicle-block-button").click(function () { | |||
|       sortChronologically(); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".chronicle-block-button").addClass("active-view-button"); | |||
|       $(".random-block-button").removeClass("active-view-button"); | |||
|       $(".alphabetical-block-button").removeClass("active-view-button"); | |||
|     }); | |||
|     $(".random-block-button").click(function () { | |||
|       randomizeCards(".list-container .card"); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".random-block-button").addClass("active-view-button"); | |||
|       $(".chronicle-block-button").removeClass("active-view-button"); | |||
|       $(".alphabetical-block-button").removeClass("active-view-button"); | |||
|     }); | |||
|     $(".alphabetical-block-button").click(function () { | |||
|       sortAlphabetically(".list-container .card"); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".alphabetical-block-button").addClass("active-view-button"); | |||
|       $(".chronicle-block-button").removeClass("active-view-button"); | |||
|       $(".random-block-button").removeClass("active-view-button"); | |||
|     }); | |||
|     // LIST VIEW SORTING BUTTONS | |||
|     $(".chronicle-list-button").click(function () { | |||
|       sortChronologically(); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".chronicle-list-button").addClass("active-view-button"); | |||
|       $(".random-list-button").removeClass("active-view-button"); | |||
|       $(".alphabetical-list-button").removeClass("active-view-button"); | |||
|     }); | |||
|     $(".random-list-button").click(function () { | |||
|       randomizeCards(".list-container .card"); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".random-list-button").addClass("active-view-button"); | |||
|       $(".chronicle-list-button").removeClass("active-view-button"); | |||
|       $(".alphabetical-list-button").removeClass("active-view-button"); | |||
|     }); | |||
|     $(".alphabetical-list-button").click(function () { | |||
|       sortAlphabetically(".list-container .card"); | |||
|       updateLastVisibleCard(); | |||
|       updateWidthBlockView(); | |||
|       processEventCards(); | |||
|       updateViews(); | |||
|       $(".alphabetical-list-button").addClass("active-view-button"); | |||
|       $(".chronicle-list-button").removeClass("active-view-button"); | |||
|       $(".random-list-button").removeClass("active-view-button"); | |||
|     }); | |||
|   } | |||
|   // FILTERS  ---------------------   SECTION // | |||
|   // General Filters Toggle Button | |||
|   $(".general-toggle").click(function () { | |||
|     var filtersDiv = $("#filters"); | |||
|     var resetButton = $(".reset-button"); | |||
|     filtersDiv.toggleClass("is-visible"); | |||
|     if (filtersDiv.hasClass("is-visible")) { | |||
|       filtersDiv.css("display", "grid").hide().slideDown(100); | |||
|       $(this).text("[FILTER]"); | |||
|       // Attach click handler to document | |||
|       $(document).on("mousedown.hideFilters", function (event) { | |||
|         var isOutsideFilters = | |||
|           !filtersDiv.is(event.target) && | |||
|           filtersDiv.has(event.target).length === 0; | |||
|         var isOnToggle = $(event.target).closest(".general-toggle").length > 0; | |||
|         if (isOutsideFilters && !isOnToggle) { | |||
|           filtersDiv.removeClass("is-visible").slideUp(100, function () { | |||
|              $(this).css("display", "none"); | |||
|           }); | |||
|           $(".general-toggle").text("[FILTER]"); | |||
|           // Remove the document click handler | |||
|           $(document).off("mousedown.hideFilters"); | |||
|         } | |||
|       }); | |||
|     } else { | |||
|       filtersDiv.slideUp(100, function () { | |||
|         $(this).css("display", "none"); | |||
|       }); | |||
|       $(this).text("[FILTER]"); | |||
|       // Remove the document click handler | |||
|       $(document).off("mousedown.hideFilters"); | |||
|     } | |||
|     updateLastVisibleCard(); | |||
|     updateWidthBlockView(); | |||
|     processEventCards(); | |||
|     updateViews(); | |||
|   }); | |||
|   // Specific Toggle for Filter Sections like TYPE, ENTITY, etc. | |||
|   $(".open-filter").click(function (event) { | |||
|     event.stopPropagation(); | |||
|     var filterType = $(this).closest(".filter").data("filter"); | |||
|     var cardSelector = $(".card").length > 0 ? ".card" : ".community-card"; // Determine which card type is present | |||
|     console.log("Filter type:", filterType, "Card Selector:", cardSelector); | |||
|     $("#values-" + filterType).toggle(); | |||
|     if ($("#values-" + filterType).is(":visible")) { | |||
|       $(this).addClass("active-filter"); | |||
|     } else { | |||
|       $(this).removeClass("active-filter"); | |||
|     } | |||
|     // Pass the determined card selector to the function | |||
|     updateLastVisibleCard(cardSelector); | |||
|     updateWidthBlockView(cardSelector); | |||
|     processEventCards(cardSelector); | |||
|     updateViews(cardSelector); | |||
|     console.log("Updated views and borders after filter toggle"); | |||
|   }); | |||
|   function filterCards() { | |||
|     var displayCountsHtml = ""; | |||
|     var cardSelector = $(".card").length > 0 ? ".card" : ".community-card"; // Determine which card type is present | |||
|     $(".filter .values a[title]").each(function () { | |||
|       var anchor = $(this); | |||
|       var filterValue = anchor.attr("title").toLowerCase(); | |||
|       var count = 0; | |||
|       if (anchor.find("button").hasClass("active")) { | |||
|         $(cardSelector).each(function () { | |||
|           var card = $(this); | |||
|           $(".filter").each(function () { | |||
|             var filterType = $(this).data("filter"); | |||
|             var cardValue = card | |||
|               .find("." + filterType) | |||
|               .text() | |||
|               .toLowerCase(); | |||
|             if (cardValue.indexOf(filterValue) !== -1) { | |||
|               count++; | |||
|              } | |||
|           }); | |||
|         }); | |||
|         displayCountsHtml += | |||
|           "<span>[" + count + "] " + filterValue + "</span> "; | |||
|       } | |||
|     }); | |||
|     if (displayCountsHtml) { | |||
|       $(".count-filtered-cards").html(displayCountsHtml).show(); | |||
|     } else { | |||
|       $(".count-filtered-cards").hide(); | |||
|     } | |||
|     // Apply filtering and pass the determined card selector to the function | |||
|     applyFiltering(cardSelector); | |||
|     updateLastVisibleCard(cardSelector); | |||
|     updateWidthBlockView(cardSelector); | |||
|     processEventCards(cardSelector); | |||
|     updateViews(cardSelector); | |||
|     console.log("Filtering process complete, updated views and borders"); | |||
|   } | |||
|   function applyFiltering() { | |||
|     // Determine which card selector to use based on the elements present in the DOM | |||
|     var cardSelector = $(".card").length > 0 ? ".card" : ".community-card"; | |||
|     // Apply the logic to the determined card type | |||
|     $(cardSelector) | |||
|       .show() | |||
|       .each(function () { | |||
|         var card = $(this); | |||
|         var hideCard = false; | |||
|         $(".filter").each(function () { | |||
|           if (hideCard) return; | |||
|           var filterType = $(this).data("filter"); | |||
|           var activeFilters = $(this) | |||
|             .find(".values a[title] button.active") | |||
|             .map(function () { | |||
|               return $(this).parent("a").attr("title").toLowerCase(); | |||
|             }) | |||
|             .get(); | |||
|           if (activeFilters.length > 0) { | |||
|             var cardValue = card | |||
|               .find("." + filterType) | |||
|               .text() | |||
|               .toLowerCase(); | |||
|             var matchesFilter = activeFilters.some(function (filterValue) { | |||
|               return cardValue.indexOf(filterValue) !== -1; | |||
|             }); | |||
|             if (!matchesFilter) hideCard = true; | |||
|           } | |||
|          }); |          }); | ||
|         if (hideCard) card.hide(); | |||
|       }); | |||
|   } | |||
|   function updateLastVisibleCard() { | |||
|     // Target only the list view container for updating the last visible card | |||
|     $(".home-chronicle-list div.list-container div.card").removeClass( | |||
|       "last-visible" | |||
|     ); | |||
|     // Find the last visible card within the list view and add the class | |||
|     var lastVisibleCard = $( | |||
|       ".home-chronicle-list div.list-container div.card:visible:last" | |||
|     ); | |||
|     lastVisibleCard.addClass("last-visible"); | |||
|   } | |||
|   function updateWidthBlockView() { | |||
|     // Target only the block view container for updating the with of card | |||
|     $(".home-chronicle-block div.list-container").css("width", "100%"); | |||
|     $(".home-chronicle-block div.list-container div.card").css( | |||
|       "width", | |||
|       "calc(20% - 0px)" | |||
|     ); | |||
|     $( | |||
|       ".home-chronicle-block div.list-container div.card:nth-child(5n + 1)" | |||
|     ).css("width", "calc(20% + 4px)"); | |||
|   } | |||
|   // Reset function to remove active filters | |||
|   $(".reset-filter").click(function (event) { | |||
|     event.stopPropagation(); // Prevent event bubbling | |||
|     // Remove 'active' class from all filter buttons | |||
|     $("#filters .values button").removeClass("active"); | |||
|     $(".open-filter").removeClass("active-filter"); | |||
|     // Reset and hide the filter counts | |||
|     $(".count-filtered-cards").text("").hide(); | |||
|     filterCards(); // Reapply filtering based on the updated active buttons | |||
|     // Update other UI elements as needed, excluding the general toggle button | |||
|     updateLastVisibleCard(); | |||
|     updateWidthBlockView(); | |||
|     processEventCards(); | |||
|     updateViews(); | |||
|   }); | |||
|   $("#filters .values button").click(function () { | |||
|     console.log("Filter is clicked!!!"); | |||
|     $(this).toggleClass("active"); | |||
|     filterCards(); // Re-apply the filters based on the updated active buttons | |||
|     updateLastVisibleCard(); | |||
|     updateWidthBlockView(); | |||
|     processEventCards(); | |||
|     updateViews(); | |||
|   }); | |||
|   // Hide filters when window is scrolled | |||
|   $(window).on("scroll", function () { | |||
|     var filtersDiv = $("#filters"); | |||
|     if (filtersDiv.hasClass("is-visible")) { | |||
|       filtersDiv.removeClass("is-visible").slideUp(100, function () { | |||
|         $(this).css("display", "none"); | |||
|         // The filter reset code has been removed to keep the filters active | |||
|       }); | |||
|       $(".general-toggle").text("[FILTER]"); // Update the toggle button text | |||
|     } | |||
|   }); | |||
|   // MODAL ARTICLE  ---------------------   SECTION // | |||
|   // Format paragraphs | |||
|   function formatParagraphs(text) { | |||
|     var paragraphs = text.split("\n").filter(function (p) { | |||
|       return p.trim() !== ""; | |||
|      }); |      }); | ||
|     return paragraphs | |||
|       .map(function (p) { | |||
|         return "<p>" + p.trim() + "</p>"; | |||
|       }) | |||
|       .join(""); | |||
|   } | |||
|   var images = []; // Initialize an empty array to store the images | |||
|   // Find all image containers within the article content and extract the necessary information | |||
|   $(".article-images .image-container").each(function () { | |||
|     var img = $(this).find("img"); | |||
|     var captionDiv = $(this).find('div[class^="caption-image"]'); | |||
|     var image = { | |||
|       src: img.attr("src"), | |||
|       alt: img.attr("alt"), | |||
|       caption: captionDiv.text(), | |||
|       captionClass: captionDiv.attr("class"), | |||
|     }; | |||
|     images.push(image); // Add the image object to the images array | |||
|   }); | |||
|   if (images.length > 0) { | |||
|     setupImageToggle(images); // Call the setupImageToggle function with the images array | |||
|     updateImageLabel(1, images.length); // Set the label for the first image immediately | |||
|   } | |||
|   function setupImageToggle(images) { | |||
|     var currentIndex = 0; | |||
|     var enableNavigation = images.length > 1; // Enable navigation only if there is more than one image | |||
|     function showImage(index) { | |||
|       currentIndex = index; | |||
|       var image = images[currentIndex]; | |||
|       updateImageLabel(currentIndex + 1, images.length); | |||
|       $("#article-content") | |||
|         .find(".article-images") | |||
|         .html( | |||
|           getImageHtml(image, currentIndex, images.length, enableNavigation) | |||
|         ); | |||
|     } | |||
|     // Attach click handlers only if navigation is enabled | |||
|     if (enableNavigation) { | |||
|       $("#article-content").on("click", ".next-arrow", function () { | |||
|         showImage((currentIndex + 1) % images.length); | |||
|       }); | |||
|       $("#article-content").on("click", ".prev-arrow", function () { | |||
|         showImage((currentIndex - 1 + images.length) % images.length); | |||
|       }); | |||
|     } | |||
|     // Display the first image | |||
|     showImage(currentIndex); | |||
|   } | |||
|   function getImageHtml(image, currentIndex, totalImages, enableNavigation) { | |||
|     var imageLabel = currentIndex + 1 + "/" + totalImages + " IMAGES"; | |||
|     // Render navigation arrows based on the enableNavigation flag | |||
|     var navigationHtml = enableNavigation | |||
|       ? '<div class="prev-arrow"><</div><div class="next-arrow">></div>' | |||
|       : ""; | |||
|     return ( | |||
|       '<div class="image-navigation">' + | |||
|       '<p class="article-label-image">' + | |||
|       imageLabel + | |||
|       "</p>" + | |||
|       '<div class="image-container">' + | |||
|       '<div class="arrows-and-image">' + | |||
|       navigationHtml + | |||
|       '<img src="' + | |||
|       image.src + | |||
|       '" alt="' + | |||
|       image.alt + | |||
|       '">' + | |||
|       "</div>" + | |||
|       '<div class="' + | |||
|       image.captionClass + | |||
|       '">' + | |||
|       image.caption + | |||
|       "</div>" + | |||
|       "</div>" + | |||
|       "</div>" | |||
|     ); | |||
|   } | |||
|   function updateImageLabel(currentIndex, totalImages) { | |||
|     var imageLabel = currentIndex + "/" + totalImages + " IMAGES"; | |||
|     $("#article-content .article-label-image").text(imageLabel); | |||
|   } | |||
|   $(".caption-image1").each(function () { | |||
|     // Split the caption at each <br> tag and wrap each line in a span | |||
|     var htmlContent = $(this).html(); | |||
|     var lines = htmlContent.split("<br>"); | |||
|     var wrappedLines = lines.map(function (line) { | |||
|       return '<span class="caption-line">' + line + "</span>"; | |||
|     }); | |||
|     var newHtml = wrappedLines.join("<br>"); | |||
|     $(this).html(newHtml); | |||
|   }); | |||
|   function setShowArticleRotationEffect() { | |||
|     const offset = 20; | |||
|     const showArticle = document.querySelector("#show-article"); | |||
|     const h = showArticle.clientHeight; | |||
|     const theta = -Math.atan(offset / h); | |||
|     const a = Math.cos(theta); | |||
|     const b = Math.sin(theta); | |||
|     const c = -Math.sin(theta); | |||
|     const d = Math.cos(theta); | |||
|     const showArticleBefore = document.querySelector("#show-article-before"); | |||
|     const transformValue = | |||
|       "matrix(" + a + "," + b + "," + c + "," + d + ",0,0)"; | |||
|     showArticleBefore.style.transform = transformValue; | |||
|   } | |||
|   function openEvent(element, event) { | |||
|     event.stopPropagation(); | |||
|     event.preventDefault(); | |||
|     var url = $(element).find(".link a").attr("href"); | |||
|     if (url) { | |||
|       window.open(url, "_blank").focus(); | |||
|     } | |||
|   } | |||
|   function openModal(cardElement, event) { | |||
|     event.stopPropagation(); | |||
|     $("#print-chooser").hide(); | |||
|     $("#show-article").removeClass("print-opts-open"); | |||
|     var pageTitle = $(cardElement).data("page") || null; // e.g. "090" | |||
|     window.currentEntryTitle = pageTitle; | |||
|     var isRelatedArticle = $(cardElement).hasClass("related-article"); | |||
|     showArticleWrapper.css("display", "block"); | |||
|     // Clear existing content in modal | |||
|     $("#article-title").empty(); | |||
|     $("#article-content").empty(); | |||
|     if (isRelatedArticle) { | |||
|       // Handle card elements (existing logic) | |||
|       var cardImages = []; | |||
|       for (var i = 1; i <= 5; i++) { | |||
|         var imageClass = ".related-article-image" + i; | |||
|         var captionClass = ".related-article-caption-image" + i; | |||
|         var imageElem = $(cardElement).find(imageClass + " img"); | |||
|         if (imageElem.length) { | |||
|           var captionText = $(cardElement) | |||
|             .find(imageClass + " " + captionClass) | |||
|             .text(); | |||
|           cardImages.push({ | |||
|             link: $(cardElement) | |||
|               .find(imageClass + " a") | |||
|               .attr("href"), | |||
|             src: imageElem.attr("src"), | |||
|             alt: imageElem.attr("alt"), | |||
|             caption: captionText, | |||
|             captionClass: "related-article-caption-image" + i, | |||
|           }); | |||
|         } | |||
|       } | |||
|       if (cardImages.length > 1) { | |||
|         setupImageToggle(cardImages); | |||
|       } | |||
|       // Handle related-article elements | |||
|       var entryNumber = $(cardElement) | |||
|         .find(".related-article-entry-number") | |||
|         .text(); | |||
|       var peopleHtml = $(cardElement).find(".related-article-people").html(); | |||
|       var title = $(cardElement).find(".related-article-title").text(); | |||
|       var typeHtml = $(cardElement).find(".related-article-type").html(); | |||
|       var externalPdfURL = $(cardElement) | |||
|         .find(".related-article-pdf a") | |||
|         .attr("href"); | |||
|       var externalLinkURL = $(cardElement) | |||
|         .find(".related-article-link a") | |||
|         .attr("href"); | |||
|       var entity = $(cardElement).find(".related-article-entity").text(); | |||
|       var discipline = $(cardElement) | |||
|         .find(".related-article-discipline") | |||
|         .text(); | |||
|       var subjectHtml = $(cardElement).find(".related-article-subject").html(); | |||
|       var description = $(cardElement) | |||
|         .find(".related-article-description") | |||
|         .html(); | |||
|       var reflection = $(cardElement) | |||
|         .find(".related-article-reflection") | |||
|         .html(); | |||
|       var quote = $(cardElement).find(".related-article-quote").text(); | |||
|       var modificationDate = $(cardElement) | |||
|         .find(".related-article-modification-date") | |||
|         .text(); | |||
|       // Update modal content for related-article | |||
|       $("#article-title").html( | |||
|         '<p class="article-entry-number">' + | |||
|           entryNumber + | |||
|           '</p><p class="article-people">' + | |||
|           peopleHtml + | |||
|           "</p>" | |||
|       ); | |||
|       var articleContentHtml = '<div class="article-title-link">'; | |||
|       articleContentHtml += '<p class="article-title">' + title + "</p>"; | |||
|       // Create a div that will wrap the links | |||
|       articleContentHtml += '<div class="link-pdf">'; | |||
|       if (externalPdfURL) { | |||
|         articleContentHtml += | |||
|           '<a href="' + | |||
|           externalPdfURL + | |||
|           '" target="_blank" class="pdf-link-icon">[PDF<span class="text-symbol">⤴</span>]</a>'; | |||
|       } | |||
|       if (externalLinkURL) { | |||
|         articleContentHtml += | |||
|           '<a href="' + | |||
|           externalLinkURL + | |||
|           '" target="_blank" class="external-link-icon">[WEB<span class="text-symbol">⤴</span>]</a>'; | |||
|       } | |||
|       // Close the .link-pdf div | |||
|       articleContentHtml += "</div>"; | |||
|       articleContentHtml += "</div>"; // Close the container div | |||
|       // Append type, entity, discipline, and subject details | |||
|       articleContentHtml += | |||
|         '<p class="article-type">' + | |||
|         typeHtml + | |||
|         "</p>" + | |||
|         '<div class="article-metadata">' + | |||
|         '<div class="article-metadata-column">' + | |||
|         '<p class="article-metadata-label">Entity</p>' + | |||
|         '<p class="article-metadata-value">' + | |||
|         entity + | |||
|         "</p>" + | |||
|         "</div>" + | |||
|         '<div class="article-metadata-column">' + | |||
|         '<p class="article-metadata-label">Discipline</p>' + | |||
|         '<p class="article-metadata-value">' + | |||
|         discipline + | |||
|         "</p>" + | |||
|         "</div>" + | |||
|         '<div class="article-metadata-column">' + | |||
|         '<p class="article-metadata-label">Subject(s)</p>' + | |||
|         '<p class="article-metadata-value">' + | |||
|         subjectHtml + | |||
|         "</p>" + | |||
|         "</div>" + | |||
|         "</div>"; | |||
|       // Add images if any | |||
|       if (cardImages.length > 0) { | |||
|         var initialImage = cardImages[0]; // Use the first image initially | |||
|         var enableNavigation = cardImages.length > 1; // Enable navigation only if more than one image | |||
|         articleContentHtml += | |||
|           '<div class="article-images">' + | |||
|           getImageHtml(initialImage, 0, cardImages.length, enableNavigation) + | |||
|           "</div>"; | |||
|       } | |||
|       // Add non-image content (description, reflection, etc.) | |||
|       articleContentHtml += | |||
|         (description | |||
|           ? '<p class="article-label-description">Description</p>' + | |||
|             '<div class="article-description">' + | |||
|             formatParagraphs(description) + | |||
|             "</div>" | |||
|           : "") + | |||
|         (reflection | |||
|           ? '<p class="article-label-reflection">Reflection</p>' + | |||
|             '<div class="article-reflection">' + | |||
|             formatParagraphs(reflection) + | |||
|             "</div>" | |||
|           : "") + | |||
|         (quote | |||
|           ? '<p class="article-label-quote">Quote</p>' + | |||
|             '<p class="article-quote">' + | |||
|             quote + | |||
|             "</p>" | |||
|           : "") + | |||
|         '<p class="article-label-modification-date">Added on</p>' + | |||
|         '<div class="article-modification-date">' + | |||
|         modificationDate + | |||
|         "</div>"; | |||
|       $("#article-content").html(articleContentHtml); | |||
|     } else { | |||
|       // Handle card elements (existing logic) | |||
|       var cardImages = []; | |||
|       for (var i = 1; i <= 5; i++) { | |||
|         var imageClass = ".image" + i; | |||
|         var captionClass = ".caption-image" + i; | |||
|         var imageElem = $(cardElement).find(imageClass + " img"); | |||
|         if (imageElem.length) { | |||
|           var captionText = $(cardElement) | |||
|             .find(imageClass + " " + captionClass) | |||
|             .text(); | |||
|           cardImages.push({ | |||
|             link: $(cardElement) | |||
|               .find(imageClass + " a") | |||
|               .attr("href"), | |||
|             src: imageElem.attr("src"), | |||
|             alt: imageElem.attr("alt"), | |||
|             caption: captionText, | |||
|             captionClass: "caption-image" + i, | |||
|           }); | |||
|         } | |||
|       } | |||
|       if (cardImages.length > 1) { | |||
|         setupImageToggle(cardImages); | |||
|       } | |||
|       var entryNumber = $(cardElement).find(".entry-number").text(); | |||
|       var title = $(cardElement).find(".title").text(); | |||
|       var peopleHtml = $(cardElement).find(".people").html(); | |||
|       var typeHtml = $(cardElement).find(".type").html(); | |||
|       var externalPdfURL = $(cardElement).find(".pdf a").attr("href"); | |||
|       var externalLinkURL = $(cardElement).find(".link a").attr("href"); | |||
|       var entity = $(cardElement).find(".entity").text(); | |||
|       var discipline = $(cardElement).find(".discipline").text(); | |||
|       var subjectHtml = $(cardElement).find(".subject").html(); | |||
|       var description = $(cardElement).find(".description").html(); | |||
|       var reflection = $(cardElement).find(".reflection").html(); | |||
|       var quote = $(cardElement).find(".quote").text(); | |||
|       var externalReferenceHtml = $(cardElement) | |||
|         .find(".external-reference") | |||
|         .html(); | |||
|       var modificationDate = $(cardElement).find(".modification-date").text(); | |||
|       var relatedArticlesHtml = $(cardElement).find(".related-articles").html(); | |||
|       $("#article-title").html( | |||
|         '<p class="article-entry-number">' + | |||
|           entryNumber + | |||
|           '</p><p class="article-people">' + | |||
|           peopleHtml + | |||
|           "</p>" | |||
|       ); | |||
|       var articleContentHtml = '<div class="article-title-link">'; | |||
|       articleContentHtml += '<p class="article-title">' + title + "</p>"; | |||
|       // Create a div that will wrap the links | |||
|       articleContentHtml += '<div class="link-pdf">'; | |||
|       if (externalPdfURL) { | |||
|         articleContentHtml += | |||
|           '<a href="' + | |||
|           externalPdfURL + | |||
|           '" target="_blank" class="pdf-link-icon">[PDF<span class="text-symbol">⤴</span>]</a>'; | |||
|       } | |||
|       if (externalLinkURL) { | |||
|         articleContentHtml += | |||
|           '<a href="' + | |||
|           externalLinkURL + | |||
|           '" target="_blank" class="external-link-icon">[WEB<span class="text-symbol">⤴</span>]</a>'; | |||
|       } | |||
|       // Close the .link-pdf div | |||
|       articleContentHtml += "</div>"; | |||
|       articleContentHtml += "</div>"; // Close the new div | |||
|       // Append type, entity, discipline, and subject details | |||
|       articleContentHtml += | |||
|         '<p class="article-type">' + | |||
|         typeHtml + | |||
|         "</p>" + | |||
|         '<div class="article-metadata">' + | |||
|         '<div class="article-metadata-column">' + | |||
|         '<p class="article-metadata-label">Entity</p>' + | |||
|         '<p class="article-metadata-value">' + | |||
|         entity + | |||
|         "</p>" + | |||
|         "</div>" + | |||
|         '<div class="article-metadata-column">' + | |||
|         '<p class="article-metadata-label">Discipline</p>' + | |||
|         '<p class="article-metadata-value">' + | |||
|         discipline + | |||
|         "</p>" + | |||
|         "</div>" + | |||
|         '<div class="article-metadata-column">' + | |||
|         '<p class="article-metadata-label">Subject(s)</p>' + | |||
|         '<p class="article-metadata-value">' + | |||
|         subjectHtml + | |||
|         "</p>" + | |||
|         "</div>" + | |||
|         "</div>"; | |||
|       // Add images if any | |||
|       if (cardImages.length > 0) { | |||
|         var initialImage = cardImages[0]; // Use the first image initially | |||
|         var enableNavigation = cardImages.length > 1; // Enable navigation only if more than one image | |||
|         articleContentHtml += | |||
|           '<div class="article-images">' + | |||
|           getImageHtml(initialImage, 0, cardImages.length, enableNavigation) + | |||
|           "</div>"; | |||
|       } | |||
|       // Add non-image content (description, reflection, etc.) | |||
|       articleContentHtml += | |||
|         (description | |||
|           ? '<p class="article-label-description">Description</p>' + | |||
|             '<div class="article-description">' + | |||
|             formatParagraphs(description) + | |||
|             "</div>" | |||
|           : "") + | |||
|         (reflection | |||
|           ? '<p class="article-label-reflection">Reflection</p>' + | |||
|             '<div class="article-reflection">' + | |||
|             formatParagraphs(reflection) + | |||
|             "</div>" | |||
|           : "") + | |||
|         (externalReferenceHtml | |||
|           ? '<p class="article-label-external-reference">References</p>' + | |||
|             '<p class="article-external-reference">' + | |||
|             externalReferenceHtml + | |||
|             "</p>" | |||
|           : "") + | |||
|         (quote | |||
|           ? '<p class="article-label-quote">Quote</p>' + | |||
|             '<p class="article-quote">' + | |||
|             quote + | |||
|             "</p>" | |||
|           : "") + | |||
|         '<p class="article-label-modification-date">Added on</p>' + | |||
|         '<div class="article-modification-date">' + | |||
|         modificationDate + | |||
|         "</div>"; | |||
|       $("#article-content").html(articleContentHtml); | |||
|       $("#related-articles").html(relatedArticlesHtml); | |||
|       if (relatedArticlesHtml && relatedArticlesHtml.trim().length > 0) { | |||
|         $("#related-articles") | |||
|           .html( | |||
|             '<div class="related-articles-label">Related Articles</div><div class="related-articles-container">' + | |||
|               relatedArticlesHtml + | |||
|               "</div>" | |||
|           ) | |||
|           .show(); | |||
|       } | |||
|     } | |||
|     // Check which view is active and set the width accordingly | |||
|     if ($(".home-chronicle-list").is(":visible")) { | |||
|       $(".home-list-view").each(function () { | |||
|         var currentWidth = $(this).width(); // Get the current width | |||
|         $(this).data("originalWidth", currentWidth); // Store the original width | |||
|         $(this).css("width", "calc(60% - 2px)"); | |||
|       }); | |||
|       // Modify the .type elements within .home-chronicle-list | |||
|       $(".home-chronicle-list .type").each(function () { | |||
|         var currentLeft = $(this).css("left"); // Get the current left value | |||
|         $(this).data("originalLeft", currentLeft); // Store the original left value | |||
|         $(this).css("left", "85%"); | |||
|       }); | |||
|     } else if ($(".home-chronicle-block").is(":visible")) { | |||
|       $(".home-chronicle-block div.list-container").each(function () { | |||
|         var currentWidth = $(this).width(); // Get the current width | |||
|         $(this).css("width", "calc(60% - 0px)"); // Set the new width as 30% of the current width | |||
|       }); | |||
|       $(".home-chronicle-block div.list-container div.card").each(function () { | |||
|         var currentWidth = $(this).width(); // Get the current width | |||
|         $(this).css("width", "calc(33.333% - 0px)"); // Set the new width as 30% of the current width | |||
|       }); | |||
|     } | |||
|     // Apply the fade-out effect to both #list and #list-list elements | |||
|     $(".list-container").addClass("fade-out"); | |||
|   } | |||
|   // closeModal function | |||
|   function closeModal() { | |||
|     $("#print-chooser").hide(); | |||
|     $("#show-article").removeClass("print-opts-open"); | |||
|     if ($(".home-chronicle-list").is(":visible")) { | |||
|       $(".home-list-view").css("width", "100%"); | |||
|       $(".home-chronicle-list div.list-container div.card div.type").css( | |||
|         "left", | |||
|         "90%" | |||
|       ); | |||
|     } else if ($(".home-chronicle-block").is(":visible")) { | |||
|       updateWidthBlockView(); | |||
|     } | |||
|     showArticleWrapper.hide(); | |||
|   } | |||
|   $(".card").on("click", function (event) { | |||
|     // Check if the click event is originating from a link within .people or .type, or any other specific area | |||
|     if ($(event.target).closest(".people a, .type a").length) { | |||
|       // The click is inside a link; let the default behavior proceed without opening the modal | |||
|       return; | |||
|     } | |||
|     // Prevent further event handling if the card has the 'event' class | |||
|     if ($(this).hasClass("event")) { | |||
|       event.stopImmediatePropagation(); | |||
|       openEvent(this, event); | |||
|       $(".list-container").removeClass("fade-out"); | |||
|       closeModal(); | |||
|     } else { | |||
|       // Handle cards without the 'event' class | |||
|       openModal(this, event); | |||
|       setShowArticleRotationEffect(); | |||
|     } | |||
|   }); | |||
|   $("#show-article-wrapper").on("click", ".related-article", function (event) { | |||
|     openModal(this, event); // Call openModal when a related-article is clicked | |||
|     setShowArticleRotationEffect(); | |||
|   }); | |||
|   // HERE SHOULD BE THE NEW CODE!!!! | |||
|   /* ---------- Softwear PRINT (scoped, ES5-safe) ---------- */ | |||
|   /* helpers */ | |||
|   function swPrintPreloadFont() { | |||
|     var link = document.createElement("link"); | |||
|     link.rel = "preload"; | |||
|     link.as = "font"; | |||
|     link.type = "font/woff2"; | |||
|     link.href = "/fonts/HALColant-TextRegular.woff2?v=20250820"; | |||
|     link.crossOrigin = "anonymous"; | |||
|     document.head.appendChild(link); | |||
|   } | |||
|   function swPrintCacheBust(url) { | |||
|     return url + (url.indexOf("?") > -1 ? "&" : "?") + "_=" + Date.now(); | |||
|   } | |||
|   function swEnsurePrintChooser() { | |||
|     var $chooser = jQuery("#print-chooser"); | |||
|     if ($chooser.length) return $chooser; | |||
|     $chooser = jQuery( | |||
|       '<div id="print-chooser" class="print-chooser" style="display:none;">' + | |||
|         '<a href="#" id="print-with-border" class="print-choice">show border</a> ' + | |||
|         '<a href="#" id="print-no-border" class="print-choice">hide border</a>' + | |||
|         "</div>" | |||
|     ); | |||
|     jQuery("#print-button").after($chooser); | |||
|     // Bind once on the chooser to catch nested elements | |||
|     if (!$chooser.data("swBound")) { | |||
|       function chooserFire(ev, where) { | |||
|         ev = ev || window.event; | |||
|         var t = ev && (ev.target || ev.srcElement); | |||
|         var a = t && t.closest ? t.closest("a[id]") : null; | |||
|         if (!a) return; | |||
|         var id = a.getAttribute("id"); | |||
|         if (id !== "print-with-border" && id !== "print-no-border") return; | |||
|         if (ev.preventDefault) ev.preventDefault(); | |||
|         if (ev.stopImmediatePropagation) ev.stopImmediatePropagation(); | |||
|         if (ev.stopPropagation) ev.stopPropagation(); | |||
|         swHandlePrintChoice(id, (window.jQuery && jQuery(a)) || null); | |||
|         return false; | |||
|       } | |||
|       $chooser.on("pointerdown", chooserFire); | |||
|       $chooser.on("touchstart", chooserFire); | |||
|       $chooser.on("mousedown", chooserFire); | |||
|       $chooser.on("click", chooserFire); | |||
|       $chooser.data("swBound", true); | |||
|     } | |||
|     return $chooser; | |||
|   } | |||
|   function swHidePrintUI() { | |||
|     jQuery("#print-chooser").hide(); | |||
|     jQuery("#show-article").removeClass("print-opts-open"); | |||
|   } | |||
|   /* small boot probe */ | |||
|   (function () { | |||
|     try { | |||
|       console.log("[swprint] probe on load", { | |||
|         printButton: !!document.getElementById("print-button"), | |||
|         chooserExists: !!document.getElementById("print-chooser"), | |||
|         localPrintOnlyCount: jQuery(".print-only").length, | |||
|         showArticleExists: !!document.getElementById("show-article"), | |||
|       }); | |||
|     } catch (e) {} | |||
|   })(); | |||
|   /* core: build iframe and print */ | |||
|   function swBuildIframeAndPrint(printHtml, borderPref, $btn) { | |||
|     // iframe | |||
|     var iframe = document.createElement("iframe"); | |||
|     iframe.style.position = "fixed"; | |||
|     iframe.style.right = "0"; | |||
|     iframe.style.bottom = "0"; | |||
|     iframe.style.width = "0"; | |||
|     iframe.style.height = "0"; | |||
|     iframe.style.border = "0"; | |||
|     document.body.appendChild(iframe); | |||
|     var doc = iframe.contentDocument || iframe.contentWindow.document; | |||
|     doc.open(); | |||
|     doc.write( | |||
|       '<!doctype html><html><head><meta charset="utf-8"><title>Print</title></head><body></body></html>' | |||
|     ); | |||
|     doc.close(); | |||
|     // make relative URLs resolve | |||
|     var base = doc.createElement("base"); | |||
|     base.href = location.origin + "/"; | |||
|     doc.head.appendChild(base); | |||
|     // print.css | |||
|     var linkCss = doc.createElement("link"); | |||
|     linkCss.rel = "stylesheet"; | |||
|     linkCss.href = swPrintCacheBust( | |||
|       "/index.php?title=MediaWiki:Print.css&action=raw&ctype=text/css" | |||
|     ); | |||
|     var cssLoaded = new Promise(function (resolve) { | |||
|       linkCss.onload = resolve; | |||
|       linkCss.onerror = resolve; | |||
|     }); | |||
|     // font preload (inside iframe) | |||
|     var linkFont = doc.createElement("link"); | |||
|     linkFont.rel = "preload"; | |||
|     linkFont.as = "font"; | |||
|     linkFont.type = "font/woff2"; | |||
|     linkFont.href = "/fonts/HALColant-TextRegular.woff2?v=20250820"; | |||
|     linkFont.crossOrigin = "anonymous"; | |||
|     doc.head.appendChild(linkFont); | |||
|     doc.head.appendChild(linkCss); | |||
|     // inject HTML | |||
|     doc.body.innerHTML = printHtml; | |||
|     // sanitize: remove inner .print-no-border if user chose WITH border | |||
|     (function () { | |||
|       var stray = doc.querySelectorAll(".print-no-border"); | |||
|       if (borderPref === "with" && stray.length) { | |||
|         Array.prototype.forEach.call(stray, function (el) { | |||
|           el.className = (el.className || "") | |||
|             .replace(/\bprint-no-border\b/g, "") | |||
|             .trim(); | |||
|         }); | |||
|       } | |||
|     })(); | |||
|     // apply border preference to <html> | |||
|     (function () { | |||
|       var htmlEl = doc.documentElement; | |||
|       if (borderPref === "without") { | |||
|         if (htmlEl.classList) htmlEl.classList.add("print-no-border"); | |||
|         else if ( | |||
|           (" " + htmlEl.className + " ").indexOf(" print-no-border ") === -1 | |||
|         ) { | |||
|           htmlEl.className += " print-no-border"; | |||
|         } | |||
|       } else { | |||
|         if (htmlEl.classList) htmlEl.classList.remove("print-no-border"); | |||
|         else | |||
|           htmlEl.className = (htmlEl.className || "").replace( | |||
|             /\bprint-no-border\b/g, | |||
|             "" | |||
|           ); | |||
|       } | |||
|     })(); | |||
|     // OPTIONAL: glue label + body together (extra safety vs. page breaks) | |||
|     (function () { | |||
|       var style = doc.createElement("style"); | |||
|       style.textContent = | |||
|         "@media print{.sw-keep{break-inside:avoid;page-break-inside:avoid;}}"; | |||
|       doc.head.appendChild(style); | |||
|       var pairs = [ | |||
|         [".article-label-description", ".article-description"], | |||
|         [".article-label-reflection", ".article-reflection"], | |||
|         [".article-label-external-reference", ".article-external-reference"], | |||
|         [".article-label-quote", ".article-quote"], | |||
|         [".article-label-modification-date", ".article-modification-date"], | |||
|       ]; | |||
|       for (var i = 0; i < pairs.length; i++) { | |||
|         var labelSel = pairs[i][0]; | |||
|         var bodySel = pairs[i][1]; | |||
|         var labels = doc.querySelectorAll(labelSel); | |||
|         for (var j = 0; j < labels.length; j++) { | |||
|           var label = labels[j]; | |||
|           var body = label.nextElementSibling; | |||
|           if (!body || !body.matches(bodySel)) continue; | |||
|           var wrap = doc.createElement("div"); | |||
|           wrap.className = "sw-keep"; | |||
|           label.parentNode.insertBefore(wrap, label); | |||
|           wrap.appendChild(label); | |||
|           wrap.appendChild(body); | |||
|         } | |||
|       } | |||
|     })(); | |||
|     // clean empty paragraphs | |||
|     (function () { | |||
|       var ps = doc.querySelectorAll("#article-content p"); | |||
|       Array.prototype.forEach.call(ps, function (p) { | |||
|         var txt = (p.textContent || "").replace(/\u00a0/g, " ").trim(); | |||
|         var onlyBr = | |||
|           p.children && | |||
|           p.children.length === 1 && | |||
|           p.firstElementChild && | |||
|           p.firstElementChild.tagName === "BR"; | |||
|         if ( | |||
|           (!txt && !p.querySelector("img, a, strong, em, span:not(:empty)")) || | |||
|           onlyBr | |||
|         ) { | |||
|           if (p.parentNode) p.parentNode.removeChild(p); | |||
|         } | |||
|       }); | |||
|       var root = doc.getElementById("article-content"); | |||
|       if (root) { | |||
|         var kids = Array.prototype.slice.call(root.childNodes); | |||
|         for (var k = 0; k < kids.length; k++) { | |||
|           var n = kids[k]; | |||
|           if (n.nodeType === 3 && !n.textContent.replace(/\s+/g, "")) { | |||
|             root.removeChild(n); | |||
|           } | |||
|         } | |||
|       } | |||
|     })(); | |||
|     // inline micro-tweaks for print spacing | |||
|     (function () { | |||
|       var css = | |||
|         "@media print{" + | |||
|         "  .article-description p,.article-reflection p,.article-external-reference p,.article-quote p{margin:0 0 1.2mm!important;}" + | |||
|         "  .article-description p:last-child,.article-reflection p:last-child,.article-external-reference p:last-child,.article-quote p:last-child{margin-bottom:0!important;}" + | |||
|         "  .article-entry-number,.link-pdf,.article-type,.article-metadata,.article-images,.article-description,.article-reflection,.article-external-reference,.article-quote,.article-mod-line{padding-bottom:1mm!important;}" + | |||
|         "  .article-label-description + .article-description," + | |||
|         "  .article-label-reflection + .article-reflection," + | |||
|         "  .article-label-external-reference + .article-external-reference," + | |||
|         "  .article-label-quote + .article-quote," + | |||
|         "  .article-label-modification-date + .article-modification-date{margin-top:0!important;}" + | |||
|         "  .article-title-link{margin:0!important;padding:0!important;}" + | |||
|         "  .article-title-link > *{margin:0!important;}" + | |||
|         "  .link-pdf{margin-top:0!important;}" + | |||
|         "  #article-content > :last-child{padding-bottom:0!important;}" + | |||
|         "  #article-content > :last-child::after{content:none!important;}" + | |||
|         "}"; | |||
|       var style = doc.createElement("style"); | |||
|       style.type = "text/css"; | |||
|       style.appendChild(doc.createTextNode(css)); | |||
|       doc.head.appendChild(style); | |||
|     })(); | |||
|     // link tweaks (wrapping / underline) | |||
|     (function () { | |||
|       var styleFix = doc.createElement("style"); | |||
|       styleFix.textContent = | |||
|         "@media print {.article-external-reference a,.link-pdf a{white-space:nowrap!important;word-break:normal!important;overflow-wrap:normal!important;text-decoration:underline}.article-external-reference{overflow-wrap:anywhere;word-break:break-word}a[href]{position:relative}}"; | |||
|       doc.head.appendChild(styleFix); | |||
|       var refs = doc.querySelectorAll(".article-external-reference a[href]"); | |||
|       Array.prototype.forEach.call(refs, function (a) { | |||
|         var txt = (a.textContent || "").trim(); | |||
|         var href = a.getAttribute("href") || ""; | |||
|         var looksLongUrl = /^https?:\/\//i.test(txt) && txt.length > 60; | |||
|         if (looksLongUrl) { | |||
|           try { | |||
|             var u = new URL(href, doc.baseURI); | |||
|             var label = | |||
|               u.hostname + (u.pathname.replace(/\/$/, "") ? u.pathname : ""); | |||
|             if (label.length > 40) label = label.slice(0, 37) + "…"; | |||
|             a.textContent = label; | |||
|           } catch (e) { | |||
|             a.textContent = "Link"; | |||
|           } | |||
|         } | |||
|         a.style.whiteSpace = "nowrap"; | |||
|         a.style.wordBreak = "normal"; | |||
|         a.style.overflowWrap = "normal"; | |||
|       }); | |||
|     })(); | |||
|     // waits | |||
|     function waitImages() { | |||
|       var imgs = [].slice.call(doc.images || []); | |||
|       if (!imgs.length) return Promise.resolve(); | |||
|       return Promise.all( | |||
|         imgs.map(function (img) { | |||
|           if (img.decode) { | |||
|             try { | |||
|               return img.decode().catch(function () {}); | |||
|             } catch (e) {} | |||
|           } | |||
|           return new Promise(function (res) { | |||
|             if (img.complete) return res(); | |||
|             img.onload = img.onerror = function () { | |||
|               res(); | |||
|             }; | |||
|           }); | |||
|         }) | |||
|       ); | |||
|     } | |||
|     function waitFonts(timeoutMs) { | |||
|       if (!doc.fonts || !doc.fonts.ready) return Promise.resolve(); | |||
|       var ready = doc.fonts.ready; | |||
|       var t = new Promise(function (res) { | |||
|         setTimeout(res, timeoutMs || 1200); | |||
|       }); | |||
|       return Promise.race([ready, t]); | |||
|     } | |||
|     function waitSpecificFont(timeoutMs) { | |||
|       if (!doc.fonts || !doc.fonts.load) return Promise.resolve(); | |||
|       var p = Promise.all([ | |||
|         doc.fonts.load('400 16px "HALColant-TextRegular"'), | |||
|         doc.fonts.load('normal 16px "HALColant-TextRegular"'), | |||
|       ]); | |||
|       var t = new Promise(function (res) { | |||
|         setTimeout(res, timeoutMs || 1200); | |||
|       }); | |||
|       return Promise.race([p, t]); | |||
|     } | |||
|     function nextFrame() { | |||
|       return new Promise(function (res) { | |||
|         (iframe.contentWindow.requestAnimationFrame || setTimeout)(res, 0); | |||
|       }); | |||
|     } | |||
|     Promise.all([ | |||
|       cssLoaded, | |||
|       waitImages(), | |||
|       waitFonts(1200), | |||
|       waitSpecificFont(1200), | |||
|       nextFrame(), | |||
|     ]) | |||
|       .then(function () { | |||
|         // filename via document.title | |||
|         var entryNum = ""; | |||
|         var numEl = doc.querySelector(".article-entry-number"); | |||
|         if (numEl) { | |||
|           var m = (numEl.textContent || "").match(/\d+/); | |||
|           entryNum = m ? m[0] : ""; | |||
|         } | |||
|         var desiredTitle = | |||
|           (entryNum ? entryNum + "." : "") + "softwear.directory"; | |||
|         var oldIframeTitle = doc.title; | |||
|         var oldParentTitle = document.title; | |||
|         iframe.contentWindow.onafterprint = function () { | |||
|           try { | |||
|             doc.title = oldIframeTitle; | |||
|             document.title = oldParentTitle; | |||
|           } catch (e) {} | |||
|           setTimeout(function () { | |||
|             if (iframe.parentNode) iframe.parentNode.removeChild(iframe); | |||
|           }, 100); | |||
|           if ($btn && $btn.length) $btn.data("busy", false); | |||
|         }; | |||
|         doc.title = desiredTitle; | |||
|         document.title = desiredTitle; | |||
|         iframe.contentWindow.focus(); | |||
|         iframe.contentWindow.print(); | |||
|         // safety cleanup | |||
|         setTimeout(function () { | |||
|           try { | |||
|             doc.title = oldIframeTitle; | |||
|             document.title = oldParentTitle; | |||
|           } catch (e) {} | |||
|           if (iframe.parentNode) iframe.parentNode.removeChild(iframe); | |||
|           if ($btn && $btn.length) $btn.data("busy", false); | |||
|         }, 1000); | |||
|       }) | |||
|       .catch(function () { | |||
|         if ($btn && $btn.length) $btn.data("busy", false); | |||
|       }); | |||
|   } | |||
|   /* decide source & kick print */ | |||
|   function swHandlePrintChoice(id, $btn) { | |||
|     if ($btn && $btn.data("busy")) return; | |||
|     if ($btn && $btn.length) $btn.data("busy", true); | |||
|     var borderPref = id === "print-no-border" ? "without" : "with"; | |||
|     swPrintPreloadFont(); | |||
|     // prefer local .print-only (Entry page) | |||
|     var localPrintOnly = jQuery(".print-only").first(); | |||
|     if (localPrintOnly.length) { | |||
|       swHidePrintUI(); | |||
|       swBuildIframeAndPrint(localPrintOnly.prop("outerHTML"), borderPref, $btn); | |||
|       return; | |||
|     } | |||
|     // otherwise fetch by title (modal/home) | |||
|     var title = | |||
|       window.currentEntryTitle || | |||
|       (window.mw && mw.config && mw.config.get && mw.config.get("wgPageName")); | |||
|     if (!title) { | |||
|       window.print(); | |||
|       if ($btn && $btn.length) $btn.data("busy", false); | |||
|       return; | |||
|     } | |||
|     var pageUrl = | |||
|       window.mw && mw.util && mw.util.getUrl | |||
|         ? mw.util.getUrl(title) | |||
|         : "/wiki/" + String(title); | |||
|     jQuery | |||
|       .get(swPrintCacheBust(pageUrl)) | |||
|       .done(function (html) { | |||
|         var $tmp = jQuery("<div>").html(html); | |||
|         var $print = $tmp.find(".print-only").first(); | |||
|         if (!$print.length) { | |||
|           window.print(); | |||
|           if ($btn && $btn.length) $btn.data("busy", false); | |||
|           return; | |||
|         } | |||
|         swHidePrintUI(); | |||
|         swBuildIframeAndPrint($print.prop("outerHTML"), borderPref, $btn); | |||
|       }) | |||
|       .fail(function () { | |||
|         window.print(); | |||
|         jQuery("#print-button").data("busy", false); | |||
|       }); | |||
|   } | |||
|   /* bind current choice anchors (defensive, for Entry pages) */ | |||
|   function swBindChoiceAnchors() { | |||
|     var sel = "#print-with-border, #print-no-border"; | |||
|     var els = document.querySelectorAll(sel); | |||
|     for (var i = 0; i < els.length; i++) { | |||
|       (function (el) { | |||
|         if (el.__swChoiceBound) return; | |||
|         el.__swChoiceBound = true; | |||
|         // ensure clickable/accessible | |||
|         try { | |||
|           el.style.pointerEvents = el.style.pointerEvents || "auto"; | |||
|           if (!el.getAttribute("role")) el.setAttribute("role", "button"); | |||
|           if (!el.getAttribute("tabindex")) el.setAttribute("tabindex", "0"); | |||
|         } catch (e) {} | |||
|         function fire(ev) { | |||
|           if (ev && ev.preventDefault) ev.preventDefault(); | |||
|           if (ev && ev.stopImmediatePropagation) ev.stopImmediatePropagation(); | |||
|           if (ev && ev.stopPropagation) ev.stopPropagation(); | |||
|           var $a = (window.jQuery && jQuery(el)) || null; | |||
|           swHandlePrintChoice(el.id, $a); | |||
|           return false; | |||
|         } | |||
|         // early + normal phases | |||
|         el.addEventListener("pointerdown", fire, true); | |||
|         el.addEventListener("touchstart", fire, true); | |||
|         el.addEventListener("mousedown", fire, true); | |||
|         el.addEventListener("click", fire, true); | |||
|         el.addEventListener("click", fire, false); | |||
|         if (!el.onclick) el.onclick = fire; | |||
|         // keyboard | |||
|         el.addEventListener( | |||
|           "keydown", | |||
|           function (e) { | |||
|             var k = e.key || e.keyCode; | |||
|             if (k === "Enter" || k === 13 || k === " " || k === 32) fire(e); | |||
|           }, | |||
|           true | |||
|         ); | |||
|       })(els[i]); | |||
|     } | |||
|   } | |||
|   /* early global catcher (minimal) */ | |||
|   (function () { | |||
|     if (window.__swprintEarlyCatcher) return; | |||
|     window.__swprintEarlyCatcher = true; | |||
|     function routeEarly(ev) { | |||
|       var t = ev.target; | |||
|       if (!t || !t.closest) return; | |||
|       var a = t.closest("a#print-with-border, a#print-no-border"); | |||
|       if (!a) return; | |||
|       if (ev.preventDefault) ev.preventDefault(); | |||
|       if (ev.stopImmediatePropagation) ev.stopImmediatePropagation(); | |||
|       if (ev.stopPropagation) ev.stopPropagation(); | |||
|       swHandlePrintChoice(a.id, (window.jQuery && jQuery(a)) || null); | |||
|       return false; | |||
|     } | |||
|     window.addEventListener("pointerdown", routeEarly, true); | |||
|     window.addEventListener("touchstart", routeEarly, true); | |||
|     window.addEventListener("mousedown", routeEarly, true); | |||
|   })(); | |||
|   /* wiring (namespaced) */ | |||
|   jQuery(document).off("click.swprint"); | |||
|   jQuery(document).on( | |||
|     "click.swprint", | |||
|     "#print-button, #print-chooser, #print-options", | |||
|     function (e) { | |||
|       // main [print] toggler | |||
|       if (jQuery(e.target).closest("#print-button").length) { | |||
|         e.preventDefault(); | |||
|         var $chooser = swEnsurePrintChooser(); | |||
|         $chooser.css({ position: "absolute", zIndex: 99999 }); | |||
|         $chooser.toggle(); | |||
|         var visible = $chooser.is(":visible"); | |||
|         jQuery("#show-article").toggleClass("print-opts-open", visible); | |||
|         // ensure anchors are bound (important on Entry pages) | |||
|         swBindChoiceAnchors(); | |||
|         return; | |||
|       } | |||
|       // click directly on a choice link (fallback path) | |||
|       var $choice = jQuery(e.target).closest( | |||
|         "a#print-with-border, a#print-no-border" | |||
|       ); | |||
|       if (!$choice.length) return; | |||
|       e.preventDefault(); | |||
|       swHandlePrintChoice($choice.attr("id"), $choice); | |||
|     } | |||
|   ); | |||
|   // map any <button> inside chooser to its host anchor | |||
|   jQuery(document).on( | |||
|     "click.swprintChoiceBtn2", | |||
|     "#print-chooser button", | |||
|     function (e) { | |||
|       var host = this.closest( | |||
|         '[id="print-with-border"], [id="print-no-border"]' | |||
|       ); | |||
|       if (!host) return; | |||
|       e.preventDefault(); | |||
|       swHandlePrintChoice(host.id, (window.jQuery && jQuery(host)) || null); | |||
|     } | |||
|   ); | |||
|   // hide choices on ESC | |||
|   jQuery(document).on("keydown.swprint", function (e) { | |||
|     if (e && e.keyCode === 27) swHidePrintUI(); | |||
|   }); | |||
|   /* ---------- /Softwear PRINT ---------- */ | |||
|   // Close modal with Close button | |||
|   $("#close-button").on("click", function () { | |||
|     $("#print-chooser").hide(); | |||
|     $("#show-article").removeClass("print-opts-open"); | |||
|     $(".list-container").removeClass("fade-out"); | |||
|     closeModal(); | |||
|   }); | |||
|   // Close modal and remove fade out also when clicking outside of card | |||
|   $(document).on("mousedown", function (event) { | |||
|     var isOutsideWrapper = | |||
|       !showArticleWrapper.is(event.target) && | |||
|       showArticleWrapper.has(event.target).length === 0; | |||
|     var isOnCard = $(event.target).closest(".card, .list-card").length > 0; | |||
|     if (!areFiltersActive) { | |||
|       if (isOutsideWrapper && !isOnCard) { | |||
|         $(".list-container").removeClass("fade-out"); | |||
|         showArticleWrapper.css("display", "none"); | |||
|         closeModal(); // Use closeModal() for cleanup | |||
|       } | |||
|     } | |||
|   }); | |||
|   // Hover effect for scrolling | |||
|   $("#show-article-wrapper").hover( | |||
|     function () { | |||
|       // On hover, enable scrolling on #show-article-wrapper | |||
|       $(this).css("overflow-y", "auto"); | |||
|       $(this).css("overflow-x", "hidden"); | |||
|     }, | |||
|     function () { | |||
|       // On hover out, disable scrolling on #show-article-wrapper | |||
|       $(this).css("overflow-y", "hidden"); | |||
|       $(this).css("overflow-x", "hidden"); | |||
|     } | |||
|   ); | |||
|   // Format community card, when in the Community Entries page | |||
|   if ($(".community-card").length) { | |||
|     formatCommunityCardDescriptions(); | |||
|   } | |||
|   function formatCommunityCardDescriptions() { | |||
|     $(".community-card").each(function () { | |||
|       // Format paragraphs in community-description | |||
|       var descriptionContainer = $(this).find(".community-description"); | |||
|       var rawDescription = descriptionContainer.text(); | |||
|       var formattedDescription = formatParagraphs(rawDescription); | |||
|       descriptionContainer.html(formattedDescription); | |||
|       // Remove empty elements in the entire card | |||
|       $(this) | |||
|         .find("*") | |||
|         .each(function () { | |||
|           if ($(this).is(":empty") || $(this).html().trim() === "<br>") { | |||
|             $(this).remove(); | |||
|           } | |||
|         }); | |||
|     }); | |||
|   } | |||
|   // paragraph-formatting block | |||
|   if (jQuery("#show-article-wrapper-entry").length) { | |||
|     function formatParagraphs(text) { | |||
|       // split on newlines, drop empty lines, wrap each in <p> | |||
|       var parts = String(text || "").split("\n"); | |||
|       var out = []; | |||
|       for (var i = 0; i < parts.length; i++) { | |||
|         var p = parts[i].replace(/^\s+|\s+$/g, ""); | |||
|         if (p) out.push("<p>" + p + "</p>"); | |||
|       } | |||
|       return out.join(""); | |||
|     } | |||
|     jQuery( | |||
|       "#show-article .article-description, #show-article .article-reflection" | |||
|     ).each(function () { | |||
|       var $el = jQuery(this); | |||
|       if ($el.children("p").length > 0) return; // already formatted by PageForms | |||
|       var rawText = $el.text(); | |||
|       $el.html(formatParagraphs(rawText)); | |||
|     }); | |||
|   } | |||
|   // SEARCH  ---------------------   SECTION // | |||
|   // Check if div with class "mw-search-results-info" exists | |||
|   if ($(".mw-search-results-info").length) { | |||
|     // Select the child <p> element and check its content | |||
|     var $paragraph = $(".mw-search-results-info > p"); | |||
|     var currentText = $paragraph.text().trim(); | |||
|     // Check if the current text is not "There were no results matching the query." | |||
|     if (currentText !== "There were no results matching the query.") { | |||
|       // Overwrite the content with "Search results" | |||
|       $paragraph.text("Pages related to your Search"); | |||
|     } | |||
|   } | |||
|   // Object to store encountered titles | |||
|   var encounteredTitles = {}; | |||
|   // Iterate over each search result | |||
|   $(".mw-search-result-heading").each(function () { | |||
|     // Get the title of the current search result | |||
|     var title = $(this).find("a").attr("title"); | |||
|     // Check if the title has already been encountered | |||
|     if (encounteredTitles[title]) { | |||
|       // Hide the duplicate search result | |||
|       $(this).hide(); | |||
|     } else { | |||
|       // Mark the title as encountered | |||
|       encounteredTitles[title] = true; | |||
|     } | |||
|   }); | |||
|   // Remove unwanted white spaces between lines | |||
|   $(".mw-search-results-container") | |||
|     .contents() | |||
|     .filter(function () { | |||
|       return this.nodeType === 3; // Filter text nodes | |||
|     }) | |||
|     .remove(); | |||
|   // Edits regarding Search Results | |||
|   // Define the new form HTML as a string | |||
|   var newFormHtml = | |||
|     '<form action="/index.php" id="searchform">' + | |||
|     '<div id="simpleSearchSpecial" class="right-inner-addon">' + | |||
|     "<span>[ Search ]</span>" + | |||
|     '<input class="form-control" name="search" placeholder="" title="Search [alt-shift-f]" accesskey="f" id="searchInput" tabindex="1" autocomplete="off" type="search">' + | |||
|     '<span class="closing-bracket">]</span>' + | |||
|     '<input value="Special:Search" name="title" type="hidden">' + | |||
|     "</div>" + | |||
|     "</form>"; | |||
|   // Replace the div with id="searchText" with the new form | |||
|   $("#searchText").replaceWith(newFormHtml); | |||
|   // Target the button based on its complex class structure | |||
|   $(".oo-ui-actionFieldLayout-button .oo-ui-buttonInputWidget").remove(); | |||
|   // Check if #submit button exists and add event listener if it does | |||
|   var submitButton = document.querySelector("#submit"); | |||
|   if (submitButton) { | |||
|     // Add click event listener | |||
|     submitButton.addEventListener("click", function (event) { | |||
|       event.preventDefault(); // Prevent the default link behavior | |||
|       var email = "submit@softwear.directory"; | |||
|       var subject = "new entry to the softwear directory"; | |||
|       var body = | |||
|         "☺ the following content could be interesting for the directory:\n\n" + | |||
|         "[ author / creator ]\n\n" + | |||
|         "---\n\n" + | |||
|         "[ title ]\n\n" + | |||
|         "---\n\n" + | |||
|         "[ why should it be included? ]\n\n" + | |||
|         "---\n\n" + | |||
|         "[ link or pdf ]\n\n" + | |||
|         "---\n\n" + | |||
|         "[ your name / contact / social ]\n\n" + | |||
|         "---"; | |||
|       var mailtoLink = | |||
|         "mailto:" + | |||
|         encodeURIComponent(email) + | |||
|         "?subject=" + | |||
|         encodeURIComponent(subject) + | |||
|         "&body=" + | |||
|         encodeURIComponent(body).replace(/%20/g, " "); | |||
|       window.location.href = mailtoLink; | |||
|     }); | |||
|   } | |||
|   // Tooltip for "wander elsewhere..." on .card.event | |||
|   var tooltip = $( | |||
|     '<div class="tooltip-popup">wander elsewhere...</div>' | |||
|   ).appendTo("body"); | |||
|   $(".card.event").on("mouseenter", function () { | |||
|     tooltip.css("opacity", 1); | |||
|   }); | |||
|   $(".card.event").on("mousemove", function (e) { | |||
|     var offsetX = 10; // right of cursor | |||
|     var offsetY = -30; // above cursor | |||
|     tooltip.css({ | |||
|       left: e.clientX + offsetX + "px", | |||
|       top: e.clientY + offsetY + "px", | |||
|     }); | |||
|   }); | |||
|   $(".card.event").on("mouseleave", function () { | |||
|     tooltip.css("opacity", 0); | |||
|   }); | |||
|   mw.loader.using("mediawiki.api", function () { | |||
|     // Only run on form edit page | |||
|     if (mw.config.get("wgCanonicalSpecialPageName") === "FormEdit") { | |||
|       new mw.Api() | |||
|         .post({ | |||
|           action: "purge", | |||
|           titles: "Main", | |||
|         }) | |||
|         .fail(function (err) { | |||
|           // Optional: leave a minimal fallback error log | |||
|           console.warn("Main page purge failed", err); | |||
|         }); | |||
|     } | |||
|   }); | |||
| }); | }); | ||