4,554
edits
| No edit summary | No edit summary | ||
| Line 1: | Line 1: | ||
| $(document).ready(function() { | $(document).ready(function () { | ||
|   // Global variables | |||
|   var cards = $(".card"); | |||
|   var showArticleWrapper = $("#show-article-wrapper"); | |||
|   var areFiltersActive = false; | |||
|   // Make header-box in Home clickable | |||
|   $(".head-box").click(function () { | |||
|     window.location.href = "/Main_Page"; // Redirects to the home page | |||
|   }); | |||
|   // 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; | |||
|      } |      } | ||
|      function  |      $.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  |   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) { | |||
|     console.log("The #home element exists on this page."); | |||
|     // This code will only run only on the homepage. | |||
|     // Show the block view container once everything is set up | |||
|     $(".home-block-view").show(); | |||
|     $(".home-chronicle-block-button, .home-block-view-button").addClass( | |||
|       "active-view-button" | |||
|     ); | |||
|     // Initialization and Default Settings | |||
|     // 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 () { | |||
|       console.log("List view button clicked."); | |||
|       $(".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); | |||
|          event. |       $(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"); | |||
|          } |          } | ||
|       }); | |||
|          // Pass the determined card selector to the function |      } 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 |           } | ||
|          }); |          }); | ||
|      function updateWidthBlockView() { |         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); | |||
|       }); | |||
|      } |      } | ||
|      function  |      // 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>"); | |||
|      function setShowArticleRotationEffect() { |      $(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(); | |||
|     var pageTitle = $(cardElement).data("page") || null; // e.g. "090" | |||
|      window.currentEntryTitle = pageTitle; | |||
|          if ( |     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() { | |||
|     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(); | |||
|   }); | |||
|   // --- PRINT HELPERS --- | |||
|   // Warm the font cache in the *parent* document. | |||
|   function preloadFontForPrint() { | |||
|     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); | |||
|      } |     // keep it; no need to remove | ||
|   } | |||
|   // Simple cache buster | |||
|   function cacheBust(url) { | |||
|      return url + (url.indexOf("?") > -1 ? "&" : "?") + "_=" + Date.now(); | |||
|   } | |||
|   // Kill any previous print handlers | |||
|   $(document).off("click.print", "#print-button"); | |||
|   $(document).on("click.print", "#print-button", function () { | |||
|     // debounce to avoid double/racing prints | |||
|     var $btn = $("#print-button"); | |||
|     if ($btn.data("busy")) return; | |||
|     $btn.data("busy", true); | |||
|      preloadFontForPrint(); |      preloadFontForPrint(); | ||
|      var title = window.currentEntryTitle; // e.g. "090" |      var title = window.currentEntryTitle; // e.g. "090" | ||
|      if (!title) { console.warn( |      if (!title) { | ||
|       console.warn("[print] no currentEntryTitle"); | |||
|       window.print(); | |||
|       $btn.data("busy", false); | |||
|       return; | |||
|     } | |||
|      var pageUrl = mw.util.getUrl(title); |      var pageUrl = mw.util.getUrl(title); | ||
|      var pageUrlFresh =  |      var pageUrlFresh = cacheBust(pageUrl); | ||
|      console.log( |      console.log("[print] fetching page HTML:", pageUrlFresh); | ||
|      $.get(pageUrlFresh).done(function (html) { |      $.get(pageUrlFresh) | ||
|          var $tmp = $( |       .done(function (html) { | ||
|          var $print = $tmp.find( |          var $tmp = $("<div>").html(html); | ||
|          console.log( |          var $print = $tmp.find(".print-only").first(); | ||
|          console.log("[print] .print-only found:", $print.length); | |||
|          var iframe = document.createElement( |         if (!$print.length) { | ||
|          iframe.style.position =  |           console.warn("[print] no .print-only found; fallback print"); | ||
|          iframe.style.right =  |           window.print(); | ||
|          iframe.style.bottom =  |           $btn.data("busy", false); | ||
|          iframe.style.width =  |           return; | ||
|          iframe.style.height =  |         } | ||
|          iframe.style.border =  | |||
|         // Build hidden 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); |          document.body.appendChild(iframe); | ||
|          var doc = iframe.contentDocument || iframe.contentWindow.document; |          var doc = iframe.contentDocument || iframe.contentWindow.document; | ||
|          doc.open(); |          doc.open(); | ||
|          doc.write('<!doctype html><html><head><meta charset="utf-8"><title>Print</title></head><body></body></html>'); |          doc.write( | ||
|           '<!doctype html><html><head><meta charset="utf-8"><title>Print</title></head><body></body></html>' | |||
|         ); | |||
|          doc.close(); |          doc.close(); | ||
|          //  |          // Ensure relative URLs (fonts/images) resolve inside iframe | ||
|          var  |          var base = doc.createElement("base"); | ||
|         base.href = location.origin + "/"; | |||
|          doc.head.appendChild(base); | |||
|          var linkCss = doc.createElement( |         // Inject PRINT CSS (cache-busted) and await it | ||
|          linkCss.rel  |         var printCssUrl = | ||
|           "/index.php?title=MediaWiki:Print.css&action=raw&ctype=text/css"; | |||
|         var printCssFresh = cacheBust(printCssUrl); | |||
|          var linkCss = doc.createElement("link"); | |||
|          linkCss.rel = "stylesheet"; | |||
|          linkCss.href = printCssFresh; |          linkCss.href = printCssFresh; | ||
|          var cssLoaded = new Promise(function(resolve |          var cssLoaded = new Promise(function (resolve) { | ||
|           linkCss.onload = function () { | |||
|             resolve(); | |||
|           }; | |||
|           linkCss.onerror = function () { | |||
|             console.warn("[print] CSS failed to load"); | |||
|             resolve(); | |||
|           }; // don't block | |||
|          }); |          }); | ||
|          //  |          // Preload the font *inside* iframe (Chrome becomes much happier) | ||
|          var linkFont = doc.createElement( |          var linkFont = doc.createElement("link"); | ||
|          linkFont.rel =  |          linkFont.rel = "preload"; | ||
|          linkFont.as  |          linkFont.as = "font"; | ||
|          linkFont.type =  |          linkFont.type = "font/woff2"; | ||
|          linkFont.href =  |          linkFont.href = "/fonts/HALColant-TextRegular.woff2?v=20250820"; | ||
|          linkFont.crossOrigin =  |          linkFont.crossOrigin = "anonymous"; | ||
|          doc.head.appendChild(linkFont); |          doc.head.appendChild(linkFont); | ||
|          doc.head.appendChild(linkCss); |          doc.head.appendChild(linkCss); | ||
|          //  |          // Inject the printable HTML | ||
|          doc.body.innerHTML = $print.prop( |          doc.body.innerHTML = $print.prop("outerHTML"); | ||
|          //  |          // Wait helpers | ||
|          function waitImages() { |          function waitImages() { | ||
|           var imgs = Array.from(doc.images || []); | |||
|           if (!imgs.length) return Promise.resolve(); | |||
|           return Promise.all( | |||
|             imgs.map(function (img) { | |||
|               if (img.decode) return img.decode().catch(function () {}); // ignore decode failures | |||
|               return new Promise(function (res) { | |||
|                 if (img.complete) return res(); | |||
|                 img.onload = img.onerror = function () { | |||
|                   res(); | |||
|                 }; | |||
|               }); | |||
|             }) | |||
|           ); | |||
|          } |          } | ||
|          function waitFonts(timeoutMs) { |          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); | |||
|          //  |           }); | ||
|          var t = new Promise(function(res){ setTimeout(res, timeoutMs || 1200); }); |           return Promise.race([ready, t]); | ||
|         } | |||
|          // **Load the specific face** so Chrome actually uses it | |||
|          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() { |          function nextFrame() { | ||
|           return new Promise(function (res) { | |||
|             (iframe.contentWindow.requestAnimationFrame || setTimeout)(res, 0); | |||
|           }); | |||
|          } |          } | ||
|         // Extra cleanup guard (Chrome sometimes delays afterprint) | |||
|         iframe.contentWindow.onafterprint = function () { | |||
|           setTimeout(function () { | |||
|             if (iframe.parentNode) iframe.parentNode.removeChild(iframe); | |||
|           }, 100); | |||
|           $btn.data("busy", false); | |||
|         }; | |||
|          Promise.all([ |          Promise.all([ | ||
|           cssLoaded, | |||
|           waitImages(), | |||
|           waitFonts(1200), | |||
|           waitSpecificFont(1200), | |||
|          ]).then(function(){ |           nextFrame(), // settle layout | ||
|          ]).then(function () { | |||
|           try { | |||
|             iframe.contentWindow.focus(); | |||
|             iframe.contentWindow.print(); | |||
|           } finally { | |||
|             // fallback cleanup in case onafterprint doesn't fire | |||
|             setTimeout(function () { | |||
|               if (iframe.parentNode) iframe.parentNode.removeChild(iframe); | |||
|               $btn.data("busy", false); | |||
|             }, 1000); | |||
|           } | |||
|          }); |          }); | ||
|       }) | |||
|       .fail(function (xhr) { | |||
|         console.warn( | |||
|           "[print] fetch failed:", | |||
|           xhr && xhr.status, | |||
|           xhr && xhr.statusText | |||
|         ); | |||
|         window.print(); | |||
|         $("#print-button").data("busy", false); | |||
|       }); | |||
|   }); | |||
|   // Close modal with Close button | |||
|   $("#close-button").on("click", function () { | |||
|     $(".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(); | |||
|           } | |||
|          }); | |||
|      }); |      }); | ||
|   } | |||
|   // NRS ENTRIES  ---------------------   SECTION // | |||
|   console.log("Document ready!"); // Check if document ready event is triggered | |||
|   if ($("#show-article-wrapper-entry").length) { | |||
|     console.log("Element with id 'show-article-wrapper-entry' found!"); // Check if the target element exists | |||
|      //  |      // Your existing formatParagraphs function | ||
|      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(""); | ||
|      } | |||
|      //  |      // Check if ".article-description" exists and format its text | ||
|      if ($( |      if ($(".article-description").length) { | ||
|       var descriptionText = $(".article-description").text(); | |||
|       var formattedDescription = formatParagraphs(descriptionText); | |||
|       $(".article-description").html(formattedDescription); // Set the formatted text | |||
|      } |      } | ||
|      // Check if ".article-reflection" exists and format its text | |||
|     if ($(".article-reflection").length) { | |||
|       var reflectionText = $(".article-reflection").text(); | |||
|       var formattedReflection = formatParagraphs(reflectionText); | |||
|       $(".article-reflection").html(formattedReflection); // Set the formatted text | |||
|      } |      } | ||
|    } | |||
|   // 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 | |||
|      // Check if  |      if (encounteredTitles[title]) { | ||
|      if ( |       // 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"); | |||
|   console.log("Submit button:", submitButton); | |||
|   if (submitButton) { | |||
|     console.log("#submit button found."); | |||
|     // Add click event listener | |||
|     submitButton.addEventListener("click", function (event) { | |||
|       console.log("Submit button clicked."); | |||
|       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); | |||
|         }); | |||
|     } | |||
|   }); | |||
| }); | }); | ||