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); | |||
}); | |||
} | |||
}); | |||
}); | }); |