MediaWiki:Common.js: Difference between revisions
Jump to navigation
Jump to search
No edit summary |
No edit summary Tag: Manual revert |
||
(473 intermediate revisions by 2 users not shown) | |||
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 | ||
if ( | 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 | |||
if ( | function sortChronologically() { | ||
var cards = $(".list-container .card").get(); | |||
cards.sort(function (a, b) { | |||
var numberA = parseInt( | |||
$(a).find(".entry-number").text().replace(/\[|\]/g, ""), | |||
10 | |||
); | |||
var numberB = parseInt( | |||
$(b).find(".entry-number").text().replace(/\[|\]/g, ""), | |||
10 | |||
); | |||
return numberB - numberA; // Descending order | |||
}); | |||
$.each(cards, function (index, item) { | |||
$(".list-container").append(item); | |||
}); | |||
} | |||
function randomizeCards(selector) { | |||
var cards = $(selector).get(); | |||
var i = cards.length, | |||
j, | |||
temp; | |||
while (--i > 0) { | |||
j = Math.floor(Math.random() * (i + 1)); | |||
temp = cards[i]; | |||
cards[i] = cards[j]; | |||
cards[j] = temp; | |||
} | |||
$.each(cards, function (index, item) { | |||
$(selector).parent().append(item); | |||
}); | |||
} | |||
function sortAlphabetically(selector) { | |||
var cards = $(selector).get(); | |||
cards.sort(function (a, b) { | |||
var titleA = $(a).find(".title").text().toUpperCase(); | |||
var titleB = $(b).find(".title").text().toUpperCase(); | |||
return titleA < titleB ? -1 : titleA > titleB ? 1 : 0; | |||
}); | |||
$.each(cards, function (index, item) { | |||
$(selector).parent().append(item); | |||
}); | |||
} | |||
function updateViews() { | |||
// Handle cards in the list view | |||
$(".home-chronicle-list div.list-container div.card:not(.event)").each( | |||
function () { | |||
if (!$(this).closest(".home-chronicle-block").length) { | |||
var title = $(this).find(".title").detach(); | |||
var images = $(this).find(".images").detach(); | |||
// Remove existing .title-images if it exists | |||
$(this).find(".title-images").remove(); | |||
var titleImagesContainer = $( | |||
'<div class="title-images"></div>' | |||
).append(images, title); | |||
$(this).find(".people").after(titleImagesContainer); | |||
} | |||
} | |||
); | |||
// Handle cards in the block view | |||
$(".home-chronicle-block div.list-container div.card:not(.event)").each( | |||
function () { | |||
// Remove .title-images container if it exists, re-attach .title and .images to their original places | |||
var titleImagesContainer = $(this).find(".title-images"); | |||
if (titleImagesContainer.length) { | |||
var title = titleImagesContainer.find(".title").detach(); | |||
var images = titleImagesContainer.find(".images").detach(); | |||
titleImagesContainer.remove(); | |||
$(this).find(".people").after(title); | |||
$(this).find(".type").after(images); | |||
} else { | |||
// If .title-images doesn't exist, ensure .images is placed correctly | |||
var images = $(this).find(".images").detach(); | |||
$(this).find(".type").after(images); | |||
} | |||
} | |||
); | |||
} | |||
function processEventCards() { | |||
$(".card.event").each(function () { | |||
var $card = $(this); | |||
var existingContainer = $card.find(".container-people-date"); | |||
// Create container if missing | |||
if (existingContainer.length === 0) { | |||
existingContainer = $('<div class="container-people-date"></div>'); | |||
$card.append(existingContainer); // temp placement | |||
} | |||
// Detach people and date | |||
var people = $card.find(".people").detach(); | |||
var date = $card.find(".date").detach(); | |||
// BLOCK VIEW (gallery) | |||
if ($card.closest(".home-chronicle-block").length) { | |||
existingContainer.append(people).append(date); | |||
// Place container after title | |||
if (!existingContainer.is($card.find(".title").next())) { | |||
$card.find(".title").after(existingContainer); | |||
} | |||
// LIST VIEW | |||
} else if ($card.closest(".home-chronicle-list").length) { | |||
// Only append .people into container | |||
existingContainer.empty().append(people); | |||
// Place container before title | |||
$card.find(".title").before(existingContainer); | |||
// Place date after title | |||
$card.find(".title").after(date); | |||
} | |||
}); | |||
} | |||
if ($("#home").length > 0) { | |||
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); | |||
$(this).text("[FILTER]"); | |||
// Attach click handler to document | |||
$(document).on("mousedown.hideFilters", function (event) { | |||
var isOutsideFilters = | |||
!filtersDiv.is(event.target) && | |||
filtersDiv.has(event.target).length === 0; | |||
var isOnToggle = $(event.target).closest(".general-toggle").length > 0; | |||
if (isOutsideFilters && !isOnToggle) { | |||
filtersDiv.removeClass("is-visible").slideUp(100, function () { | |||
$(this).css("display", "none"); | |||
}); | |||
$(".general-toggle").text("[FILTER]"); | |||
// Remove the document click handler | |||
$(document).off("mousedown.hideFilters"); | |||
} | |||
}); | |||
} else { | |||
filtersDiv.slideUp(100, function () { | |||
$(this).css("display", "none"); | |||
}); | |||
$(this).text("[FILTER]"); | |||
// Remove the document click handler | |||
$(document).off("mousedown.hideFilters"); | |||
} | |||
updateLastVisibleCard(); | |||
updateWidthBlockView(); | |||
processEventCards(); | |||
updateViews(); | |||
}); | |||
// Specific Toggle for Filter Sections like TYPE, ENTITY, etc. | |||
$(".open-filter").click(function (event) { | |||
event.stopPropagation(); | |||
var filterType = $(this).closest(".filter").data("filter"); | |||
var cardSelector = $(".card").length > 0 ? ".card" : ".community-card"; // Determine which card type is present | |||
console.log("Filter type:", filterType, "Card Selector:", cardSelector); | |||
$("#values-" + filterType).toggle(); | |||
if ($("#values-" + filterType).is(":visible")) { | |||
$(this).addClass("active-filter"); | |||
} else { | |||
$(this).removeClass("active-filter"); | |||
} | |||
// Pass the determined card selector to the function | |||
updateLastVisibleCard(cardSelector); | |||
updateWidthBlockView(cardSelector); | |||
processEventCards(cardSelector); | |||
updateViews(cardSelector); | |||
console.log("Updated views and borders after filter toggle"); | |||
}); | |||
function filterCards() { | |||
var displayCountsHtml = ""; | |||
var cardSelector = $(".card").length > 0 ? ".card" : ".community-card"; // Determine which card type is present | |||
$(".filter .values a[title]").each(function () { | |||
var anchor = $(this); | |||
var filterValue = anchor.attr("title").toLowerCase(); | |||
var count = 0; | |||
if (anchor.find("button").hasClass("active")) { | |||
$(cardSelector).each(function () { | |||
var card = $(this); | |||
$(".filter").each(function () { | |||
var filterType = $(this).data("filter"); | |||
var cardValue = card | |||
.find("." + filterType) | |||
.text() | |||
.toLowerCase(); | |||
if (cardValue.indexOf(filterValue) !== -1) { | |||
count++; | |||
} | } | ||
}); | |||
}); | |||
displayCountsHtml += | |||
"<span>[" + count + "] " + filterValue + "</span> "; | |||
} | |||
}); | |||
if (displayCountsHtml) { | |||
$(".count-filtered-cards").html(displayCountsHtml).show(); | |||
} else { | |||
$(".count-filtered-cards").hide(); | |||
} | |||
// Apply filtering and pass the determined card selector to the function | |||
applyFiltering(cardSelector); | |||
updateLastVisibleCard(cardSelector); | |||
updateWidthBlockView(cardSelector); | |||
processEventCards(cardSelector); | |||
updateViews(cardSelector); | |||
console.log("Filtering process complete, updated views and borders"); | |||
} | |||
function applyFiltering() { | |||
// Determine which card selector to use based on the elements present in the DOM | |||
var cardSelector = $(".card").length > 0 ? ".card" : ".community-card"; | |||
// Apply the logic to the determined card type | |||
$(cardSelector) | |||
.show() | |||
.each(function () { | |||
var card = $(this); | |||
var hideCard = false; | |||
$(".filter").each(function () { | |||
if (hideCard) return; | |||
var filterType = $(this).data("filter"); | |||
$( | var activeFilters = $(this) | ||
.find(".values a[title] button.active") | |||
.map(function () { | |||
return $(this).parent("a").attr("title").toLowerCase(); | |||
}) | |||
.get(); | |||
if (activeFilters.length > 0) { | |||
var cardValue = card | |||
.find("." + filterType) | |||
.text() | |||
.toLowerCase(); | |||
var matchesFilter = activeFilters.some(function (filterValue) { | |||
return cardValue.indexOf(filterValue) !== -1; | |||
}); | |||
if (!matchesFilter) hideCard = true; | |||
} | |||
}); | }); | ||
if (hideCard) card.hide(); | |||
}); | |||
} | |||
function updateLastVisibleCard() { | |||
// Target only the list view container for updating the last visible card | |||
$(".home-chronicle-list div.list-container div.card").removeClass( | |||
"last-visible" | |||
); | |||
// Find the last visible card within the list view and add the class | |||
var lastVisibleCard = $( | |||
".home-chronicle-list div.list-container div.card:visible:last" | |||
); | |||
lastVisibleCard.addClass("last-visible"); | |||
}); | } | ||
function updateWidthBlockView() { | |||
// Target only the block view container for updating the with of card | |||
$(".home-chronicle-block div.list-container").css("width", "100%"); | |||
$(".home-chronicle-block div.list-container div.card").css( | |||
"width", | |||
"calc(20% - 0px)" | |||
); | |||
$( | |||
".home-chronicle-block div.list-container div.card:nth-child(5n + 1)" | |||
).css("width", "calc(20% + 4px)"); | |||
} | |||
// Reset function to remove active filters | |||
$(".reset-filter").click(function (event) { | |||
event.stopPropagation(); // Prevent event bubbling | |||
// Remove 'active' class from all filter buttons | |||
$("#filters .values button").removeClass("active"); | |||
$(".open-filter").removeClass("active-filter"); | |||
// Reset and hide the filter counts | |||
$(".count-filtered-cards").text("").hide(); | |||
filterCards(); // Reapply filtering based on the updated active buttons | |||
// Update other UI elements as needed, excluding the general toggle button | |||
updateLastVisibleCard(); | |||
updateWidthBlockView(); | |||
processEventCards(); | |||
updateViews(); | |||
}); | |||
$("#filters .values button").click(function () { | |||
console.log("Filter is clicked!!!"); | |||
$(this).toggleClass("active"); | |||
filterCards(); // Re-apply the filters based on the updated active buttons | |||
updateLastVisibleCard(); | |||
updateWidthBlockView(); | |||
processEventCards(); | |||
updateViews(); | |||
}); | |||
// Hide filters when window is scrolled | |||
$(window).on("scroll", function () { | |||
var filtersDiv = $("#filters"); | |||
if (filtersDiv.hasClass("is-visible")) { | |||
filtersDiv.removeClass("is-visible").slideUp(100, function () { | |||
$(this).css("display", "none"); | |||
// The filter reset code has been removed to keep the filters active | |||
}); | |||
$(".general-toggle").text("[FILTER]"); // Update the toggle button text | |||
} | |||
}); | |||
// MODAL ARTICLE --------------------- SECTION // | |||
// Format paragraphs | |||
function formatParagraphs(text) { | |||
var paragraphs = text.split("\n").filter(function (p) { | |||
return p.trim() !== ""; | |||
}); | |||
return paragraphs | |||
.map(function (p) { | |||
return "<p>" + p.trim() + "</p>"; | |||
}) | |||
.join(""); | |||
} | |||
var images = []; // Initialize an empty array to store the images | |||
// Find all image containers within the article content and extract the necessary information | |||
$(".article-images .image-container").each(function () { | |||
var img = $(this).find("img"); | |||
var captionDiv = $(this).find('div[class^="caption-image"]'); | |||
var image = { | |||
src: img.attr("src"), | |||
alt: img.attr("alt"), | |||
caption: captionDiv.text(), | |||
captionClass: captionDiv.attr("class"), | |||
}; | |||
images.push(image); // Add the image object to the images array | |||
}); | |||
if (images.length > 0) { | |||
setupImageToggle(images); // Call the setupImageToggle function with the images array | |||
updateImageLabel(1, images.length); // Set the label for the first image immediately | |||
} | |||
function setupImageToggle(images) { | |||
var currentIndex = 0; | |||
var enableNavigation = images.length > 1; // Enable navigation only if there is more than one image | |||
function showImage(index) { | |||
currentIndex = index; | |||
var image = images[currentIndex]; | |||
updateImageLabel(currentIndex + 1, images.length); | |||
$("#article-content") | |||
.find(".article-images") | |||
.html( | |||
getImageHtml(image, currentIndex, images.length, enableNavigation) | |||
); | |||
} | |||
// Attach click handlers only if navigation is enabled | |||
if (enableNavigation) { | |||
$("#article-content").on("click", ".next-arrow", function () { | |||
showImage((currentIndex + 1) % images.length); | |||
}); | |||
$("#article-content").on("click", ".prev-arrow", function () { | |||
showImage((currentIndex - 1 + images.length) % images.length); | |||
}); | |||
} | |||
// Display the first image | |||
showImage(currentIndex); | |||
} | |||
function getImageHtml(image, currentIndex, totalImages, enableNavigation) { | |||
var imageLabel = currentIndex + 1 + "/" + totalImages + " IMAGES"; | |||
// Render navigation arrows based on the enableNavigation flag | |||
var navigationHtml = enableNavigation | |||
? '<div class="prev-arrow"><</div><div class="next-arrow">></div>' | |||
: ""; | |||
return ( | |||
'<div class="image-navigation">' + | |||
'<p class="article-label-image">' + | |||
imageLabel + | |||
"</p>" + | |||
'<div class="image-container">' + | |||
'<div class="arrows-and-image">' + | |||
navigationHtml + | |||
'<img src="' + | |||
image.src + | |||
'" alt="' + | |||
image.alt + | |||
'">' + | |||
"</div>" + | |||
'<div class="' + | |||
image.captionClass + | |||
'">' + | |||
image.caption + | |||
"</div>" + | |||
"</div>" + | |||
"</div>" | |||
); | |||
} | |||
function updateImageLabel(currentIndex, totalImages) { | |||
var imageLabel = currentIndex + "/" + totalImages + " IMAGES"; | |||
$("#article-content .article-label-image").text(imageLabel); | |||
} | |||
$(".caption-image1").each(function () { | |||
// Split the caption at each <br> tag and wrap each line in a span | |||
var htmlContent = $(this).html(); | |||
var lines = htmlContent.split("<br>"); | |||
var wrappedLines = lines.map(function (line) { | |||
return '<span class="caption-line">' + line + "</span>"; | |||
}); | |||
var newHtml = wrappedLines.join("<br>"); | |||
$(this).html(newHtml); | |||
}); | |||
function setShowArticleRotationEffect() { | |||
const offset = 20; | |||
const showArticle = document.querySelector("#show-article"); | |||
const h = showArticle.clientHeight; | |||
const theta = -Math.atan(offset / h); | |||
const a = Math.cos(theta); | |||
const b = Math.sin(theta); | |||
const c = -Math.sin(theta); | |||
const d = Math.cos(theta); | |||
const showArticleBefore = document.querySelector("#show-article-before"); | |||
const transformValue = | |||
"matrix(" + a + "," + b + "," + c + "," + d + ",0,0)"; | |||
showArticleBefore.style.transform = transformValue; | |||
} | |||
function openEvent(element, event) { | |||
event.stopPropagation(); | |||
event.preventDefault(); | |||
var url = $(element).find(".link a").attr("href"); | |||
if (url) { | |||
window.open(url, "_blank").focus(); | |||
} | |||
} | |||
function openModal(cardElement, event) { | |||
event.stopPropagation(); | |||
var pageTitle = $(cardElement).data("page") || null; // e.g. "090" | |||
window.currentEntryTitle = pageTitle; | |||
var isRelatedArticle = $(cardElement).hasClass("related-article"); | |||
showArticleWrapper.css("display", "block"); | |||
// Clear existing content in modal | |||
$("#article-title").empty(); | |||
$("#article-content").empty(); | |||
if (isRelatedArticle) { | |||
// Handle card elements (existing logic) | |||
var cardImages = []; | |||
for (var i = 1; i <= 5; i++) { | |||
var imageClass = ".related-article-image" + i; | |||
var captionClass = ".related-article-caption-image" + i; | |||
var imageElem = $(cardElement).find(imageClass + " img"); | |||
if (imageElem.length) { | |||
var captionText = $(cardElement) | |||
.find(imageClass + " " + captionClass) | |||
.text(); | |||
cardImages.push({ | |||
link: $(cardElement) | |||
.find(imageClass + " a") | |||
.attr("href"), | |||
src: imageElem.attr("src"), | |||
alt: imageElem.attr("alt"), | |||
caption: captionText, | |||
captionClass: "related-article-caption-image" + i, | |||
}); | |||
} | } | ||
} | |||
if (cardImages.length > 1) { | |||
setupImageToggle(cardImages); | |||
} | |||
// Handle related-article elements | |||
var entryNumber = $(cardElement) | |||
.find(".related-article-entry-number") | |||
.text(); | |||
var peopleHtml = $(cardElement).find(".related-article-people").html(); | |||
var title = $(cardElement).find(".related-article-title").text(); | |||
var typeHtml = $(cardElement).find(".related-article-type").html(); | |||
var externalPdfURL = $(cardElement) | |||
.find(".related-article-pdf a") | |||
.attr("href"); | |||
var externalLinkURL = $(cardElement) | |||
.find(".related-article-link a") | |||
.attr("href"); | |||
var entity = $(cardElement).find(".related-article-entity").text(); | |||
var discipline = $(cardElement) | |||
.find(".related-article-discipline") | |||
.text(); | |||
var subjectHtml = $(cardElement).find(".related-article-subject").html(); | |||
var description = $(cardElement) | |||
.find(".related-article-description") | |||
.html(); | |||
var reflection = $(cardElement) | |||
.find(".related-article-reflection") | |||
.html(); | |||
var quote = $(cardElement).find(".related-article-quote").text(); | |||
var modificationDate = $(cardElement) | |||
.find(".related-article-modification-date") | |||
.text(); | |||
// Update modal content for related-article | |||
$("#article-title").html( | |||
'<p class="article-entry-number">' + | |||
entryNumber + | |||
'</p><p class="article-people">' + | |||
peopleHtml + | |||
"</p>" | |||
); | |||
var articleContentHtml = '<div class="article-title-link">'; | |||
articleContentHtml += '<p class="article-title">' + title + "</p>"; | |||
// Create a div that will wrap the links | |||
articleContentHtml += '<div class="link-pdf">'; | |||
if (externalPdfURL) { | |||
articleContentHtml += | |||
'<a href="' + | |||
externalPdfURL + | |||
'" target="_blank" class="pdf-link-icon">[PDF<span class="text-symbol">⤴</span>]</a>'; | |||
} | |||
if (externalLinkURL) { | |||
articleContentHtml += | |||
'<a href="' + | |||
externalLinkURL + | |||
'" target="_blank" class="external-link-icon">[WEB<span class="text-symbol">⤴</span>]</a>'; | |||
} | |||
// Close the .link-pdf div | |||
articleContentHtml += "</div>"; | |||
articleContentHtml += "</div>"; // Close the container div | |||
// Append type, entity, discipline, and subject details | |||
articleContentHtml += | |||
'<p class="article-type">' + | |||
typeHtml + | |||
"</p>" + | |||
'<div class="article-metadata">' + | |||
'<div class="article-metadata-column">' + | |||
'<p class="article-metadata-label">Entity</p>' + | |||
'<p class="article-metadata-value">' + | |||
entity + | |||
"</p>" + | |||
"</div>" + | |||
'<div class="article-metadata-column">' + | |||
'<p class="article-metadata-label">Discipline</p>' + | |||
'<p class="article-metadata-value">' + | |||
discipline + | |||
"</p>" + | |||
"</div>" + | |||
'<div class="article-metadata-column">' + | |||
'<p class="article-metadata-label">Subject(s)</p>' + | |||
'<p class="article-metadata-value">' + | |||
subjectHtml + | |||
"</p>" + | |||
"</div>" + | |||
"</div>"; | |||
// Add images if any | |||
if (cardImages.length > 0) { | |||
var initialImage = cardImages[0]; // Use the first image initially | |||
var enableNavigation = cardImages.length > 1; // Enable navigation only if more than one image | |||
articleContentHtml += | |||
'<div class="article-images">' + | |||
getImageHtml(initialImage, 0, cardImages.length, enableNavigation) + | |||
"</div>"; | |||
} | |||
// Add non-image content (description, reflection, etc.) | |||
articleContentHtml += | |||
(description | |||
? '<p class="article-label-description">Description</p>' + | |||
'<div class="article-description">' + | |||
formatParagraphs(description) + | |||
"</div>" | |||
: "") + | |||
(reflection | |||
? '<p class="article-label-reflection">Reflection</p>' + | |||
'<div class="article-reflection">' + | |||
formatParagraphs(reflection) + | |||
"</div>" | |||
: "") + | |||
(quote | |||
? '<p class="article-label-quote">Quote</p>' + | |||
'<p class="article-quote">' + | |||
quote + | |||
"</p>" | |||
: "") + | |||
'<p class="article-label-modification-date">Added on</p>' + | |||
'<div class="article-modification-date">' + | |||
modificationDate + | |||
"</div>"; | |||
$("#article-content").html(articleContentHtml); | |||
} else { | |||
// Handle card elements (existing logic) | |||
var cardImages = []; | |||
for (var i = 1; i <= 5; i++) { | |||
var imageClass = ".image" + i; | |||
var captionClass = ".caption-image" + i; | |||
var imageElem = $(cardElement).find(imageClass + " img"); | |||
if (imageElem.length) { | |||
var captionText = $(cardElement) | |||
.find(imageClass + " " + captionClass) | |||
.text(); | |||
cardImages.push({ | |||
link: $(cardElement) | |||
.find(imageClass + " a") | |||
.attr("href"), | |||
src: imageElem.attr("src"), | |||
alt: imageElem.attr("alt"), | |||
caption: captionText, | |||
captionClass: "caption-image" + i, | |||
}); | |||
} | } | ||
} | |||
// | |||
$( | if (cardImages.length > 1) { | ||
setupImageToggle(cardImages); | |||
} | |||
var entryNumber = $(cardElement).find(".entry-number").text(); | |||
var title = $(cardElement).find(".title").text(); | |||
var peopleHtml = $(cardElement).find(".people").html(); | |||
} | var typeHtml = $(cardElement).find(".type").html(); | ||
var externalPdfURL = $(cardElement).find(".pdf a").attr("href"); | |||
var externalLinkURL = $(cardElement).find(".link a").attr("href"); | |||
var entity = $(cardElement).find(".entity").text(); | |||
var discipline = $(cardElement).find(".discipline").text(); | |||
var subjectHtml = $(cardElement).find(".subject").html(); | |||
var description = $(cardElement).find(".description").html(); | |||
var reflection = $(cardElement).find(".reflection").html(); | |||
var quote = $(cardElement).find(".quote").text(); | |||
var externalReferenceHtml = $(cardElement) | |||
.find(".external-reference") | |||
.html(); | |||
var modificationDate = $(cardElement).find(".modification-date").text(); | |||
var relatedArticlesHtml = $(cardElement).find(".related-articles").html(); | |||
$("#article-title").html( | |||
'<p class="article-entry-number">' + | |||
entryNumber + | |||
'</p><p class="article-people">' + | |||
peopleHtml + | |||
"</p>" | |||
); | |||
var articleContentHtml = '<div class="article-title-link">'; | |||
articleContentHtml += '<p class="article-title">' + title + "</p>"; | |||
// Create a div that will wrap the links | |||
articleContentHtml += '<div class="link-pdf">'; | |||
if (externalPdfURL) { | |||
articleContentHtml += | |||
'<a href="' + | |||
externalPdfURL + | |||
'" target="_blank" class="pdf-link-icon">[PDF<span class="text-symbol">⤴</span>]</a>'; | |||
} | |||
if (externalLinkURL) { | |||
articleContentHtml += | |||
'<a href="' + | |||
externalLinkURL + | |||
'" target="_blank" class="external-link-icon">[WEB<span class="text-symbol">⤴</span>]</a>'; | |||
} | |||
// Close the .link-pdf div | |||
articleContentHtml += "</div>"; | |||
articleContentHtml += "</div>"; // Close the new div | |||
// Append type, entity, discipline, and subject details | |||
articleContentHtml += | |||
'<p class="article-type">' + | |||
typeHtml + | |||
"</p>" + | |||
'<div class="article-metadata">' + | |||
'<div class="article-metadata-column">' + | |||
'<p class="article-metadata-label">Entity</p>' + | |||
'<p class="article-metadata-value">' + | |||
entity + | |||
"</p>" + | |||
"</div>" + | |||
'<div class="article-metadata-column">' + | |||
'<p class="article-metadata-label">Discipline</p>' + | |||
'<p class="article-metadata-value">' + | |||
discipline + | |||
"</p>" + | |||
"</div>" + | |||
'<div class="article-metadata-column">' + | |||
'<p class="article-metadata-label">Subject(s)</p>' + | |||
'<p class="article-metadata-value">' + | |||
subjectHtml + | |||
"</p>" + | |||
"</div>" + | |||
"</div>"; | |||
// Add images if any | |||
if (cardImages.length > 0) { | |||
var initialImage = cardImages[0]; // Use the first image initially | |||
var enableNavigation = cardImages.length > 1; // Enable navigation only if more than one image | |||
articleContentHtml += | |||
'<div class="article-images">' + | |||
getImageHtml(initialImage, 0, cardImages.length, enableNavigation) + | |||
"</div>"; | |||
} | |||
// Add non-image content (description, reflection, etc.) | |||
articleContentHtml += | |||
(description | |||
? '<p class="article-label-description">Description</p>' + | |||
'<div class="article-description">' + | |||
formatParagraphs(description) + | |||
"</div>" | |||
: "") + | |||
(reflection | |||
? '<p class="article-label-reflection">Reflection</p>' + | |||
'<div class="article-reflection">' + | |||
formatParagraphs(reflection) + | |||
"</div>" | |||
: "") + | |||
(externalReferenceHtml | |||
? '<p class="article-label-external-reference">References</p>' + | |||
'<p class="article-external-reference">' + | |||
externalReferenceHtml + | |||
"</p>" | |||
: "") + | |||
(quote | |||
? '<p class="article-label-quote">Quote</p>' + | |||
'<p class="article-quote">' + | |||
quote + | |||
"</p>" | |||
: "") + | |||
'<p class="article-label-modification-date">Added on</p>' + | |||
'<div class="article-modification-date">' + | |||
modificationDate + | |||
"</div>"; | |||
$("#article-content").html(articleContentHtml); | |||
$("#related-articles").html(relatedArticlesHtml); | |||
if (relatedArticlesHtml && relatedArticlesHtml.trim().length > 0) { | |||
$("#related-articles") | |||
.html( | |||
'<div class="related-articles-label">Related Articles</div><div class="related-articles-container">' + | |||
relatedArticlesHtml + | |||
"</div>" | |||
) | |||
.show(); | |||
} | |||
} | |||
// Check which view is active and set the width accordingly | |||
if ($(".home-chronicle-list").is(":visible")) { | |||
$(".home-list-view").each(function () { | |||
var currentWidth = $(this).width(); // Get the current width | |||
$(this).data("originalWidth", currentWidth); // Store the original width | |||
$(this).css("width", "calc(60% - 2px)"); | |||
}); | |||
// Modify the .type elements within .home-chronicle-list | |||
$(".home-chronicle-list .type").each(function () { | |||
var currentLeft = $(this).css("left"); // Get the current left value | |||
$(this).data("originalLeft", currentLeft); // Store the original left value | |||
$(this).css("left", "85%"); | |||
}); | |||
} else if ($(".home-chronicle-block").is(":visible")) { | |||
$(".home-chronicle-block div.list-container").each(function () { | |||
var currentWidth = $(this).width(); // Get the current width | |||
$(this).css("width", "calc(60% - 0px)"); // Set the new width as 30% of the current width | |||
}); | |||
$(".home-chronicle-block div.list-container div.card").each(function () { | |||
var currentWidth = $(this).width(); // Get the current width | |||
$(this).css("width", "calc(33.333% - 0px)"); // Set the new width as 30% of the current width | |||
}); | |||
} | |||
// Apply the fade-out effect to both #list and #list-list elements | |||
$(".list-container").addClass("fade-out"); | |||
} | |||
// closeModal function | |||
function closeModal() { | |||
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(); | |||
var title = window.currentEntryTitle; // e.g. "090" | |||
if (!title) { | |||
console.warn("[print] no currentEntryTitle"); | |||
window.print(); | |||
$btn.data("busy", false); | |||
return; | |||
} | |||
var pageUrl = mw.util.getUrl(title); | |||
var pageUrlFresh = cacheBust(pageUrl); | |||
console.log("[print] fetching page HTML:", pageUrlFresh); | |||
$.get(pageUrlFresh) | |||
.done(function (html) { | |||
var $tmp = $("<div>").html(html); | |||
var $print = $tmp.find(".print-only").first(); | |||
console.log("[print] .print-only found:", $print.length); | |||
if (!$print.length) { | |||
console.warn("[print] no .print-only found; fallback print"); | |||
window.print(); | |||
$btn.data("busy", false); | |||
return; | |||
} | |||
// 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); | |||
var doc = iframe.contentDocument || iframe.contentWindow.document; | |||
doc.open(); | |||
doc.write( | |||
'<!doctype html><html><head><meta charset="utf-8"><title>Print</title></head><body></body></html>' | |||
); | |||
doc.close(); | |||
// Ensure relative URLs (fonts/images) resolve inside iframe | |||
var base = doc.createElement("base"); | |||
base.href = location.origin + "/"; | |||
doc.head.appendChild(base); | |||
// Inject PRINT CSS (cache-busted) and await it | |||
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; | |||
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("link"); | ||
// | linkFont.rel = "preload"; | ||
$( | linkFont.as = "font"; | ||
linkFont.type = "font/woff2"; | |||
linkFont.href = "/fonts/HALColant-TextRegular.woff2?v=20250820"; | |||
linkFont.crossOrigin = "anonymous"; | |||
doc.head.appendChild(linkFont); | |||
doc.head.appendChild(linkCss); | |||
// Inject the printable HTML | |||
doc.body.innerHTML = $print.prop("outerHTML"); | |||
// Wait helpers | |||
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) { | |||
if (!doc.fonts || !doc.fonts.ready) return Promise.resolve(); | |||
var ready = doc.fonts.ready; | |||
var t = new Promise(function (res) { | |||
setTimeout(res, timeoutMs || 1200); | |||
}); | |||
return Promise.race([ready, t]); | |||
} | |||
// **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() { | |||
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([ | |||
cssLoaded, | |||
waitImages(), | |||
waitFonts(1200), | |||
waitSpecificFont(1200), | |||
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() { | |||
$(this). | $(".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 ($(".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 | |||
if (encounteredTitles[title]) { | |||
// Hide the duplicate search result | |||
$(this).hide(); | |||
} else { | } 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); | |||
}); | |||
} | } | ||
}); | |||
}); | }); |
Latest revision as of 14:14, 26 August 2025
$(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; } $.each(cards, function (index, item) { $(selector).parent().append(item); }); } function sortAlphabetically(selector) { var cards = $(selector).get(); cards.sort(function (a, b) { var titleA = $(a).find(".title").text().toUpperCase(); var titleB = $(b).find(".title").text().toUpperCase(); return titleA < titleB ? -1 : titleA > titleB ? 1 : 0; }); $.each(cards, function (index, item) { $(selector).parent().append(item); }); } function updateViews() { // Handle cards in the list view $(".home-chronicle-list div.list-container div.card:not(.event)").each( function () { if (!$(this).closest(".home-chronicle-block").length) { var title = $(this).find(".title").detach(); var images = $(this).find(".images").detach(); // Remove existing .title-images if it exists $(this).find(".title-images").remove(); var titleImagesContainer = $( '<div class="title-images"></div>' ).append(images, title); $(this).find(".people").after(titleImagesContainer); } } ); // Handle cards in the block view $(".home-chronicle-block div.list-container div.card:not(.event)").each( function () { // Remove .title-images container if it exists, re-attach .title and .images to their original places var titleImagesContainer = $(this).find(".title-images"); if (titleImagesContainer.length) { var title = titleImagesContainer.find(".title").detach(); var images = titleImagesContainer.find(".images").detach(); titleImagesContainer.remove(); $(this).find(".people").after(title); $(this).find(".type").after(images); } else { // If .title-images doesn't exist, ensure .images is placed correctly var images = $(this).find(".images").detach(); $(this).find(".type").after(images); } } ); } function processEventCards() { $(".card.event").each(function () { var $card = $(this); var existingContainer = $card.find(".container-people-date"); // Create container if missing if (existingContainer.length === 0) { existingContainer = $('<div class="container-people-date"></div>'); $card.append(existingContainer); // temp placement } // Detach people and date var people = $card.find(".people").detach(); var date = $card.find(".date").detach(); // BLOCK VIEW (gallery) if ($card.closest(".home-chronicle-block").length) { existingContainer.append(people).append(date); // Place container after title if (!existingContainer.is($card.find(".title").next())) { $card.find(".title").after(existingContainer); } // LIST VIEW } else if ($card.closest(".home-chronicle-list").length) { // Only append .people into container existingContainer.empty().append(people); // Place container before title $card.find(".title").before(existingContainer); // Place date after title $card.find(".title").after(date); } }); } if ($("#home").length > 0) { 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); $(this).text("[FILTER]"); // Attach click handler to document $(document).on("mousedown.hideFilters", function (event) { var isOutsideFilters = !filtersDiv.is(event.target) && filtersDiv.has(event.target).length === 0; var isOnToggle = $(event.target).closest(".general-toggle").length > 0; if (isOutsideFilters && !isOnToggle) { filtersDiv.removeClass("is-visible").slideUp(100, function () { $(this).css("display", "none"); }); $(".general-toggle").text("[FILTER]"); // Remove the document click handler $(document).off("mousedown.hideFilters"); } }); } else { filtersDiv.slideUp(100, function () { $(this).css("display", "none"); }); $(this).text("[FILTER]"); // Remove the document click handler $(document).off("mousedown.hideFilters"); } updateLastVisibleCard(); updateWidthBlockView(); processEventCards(); updateViews(); }); // Specific Toggle for Filter Sections like TYPE, ENTITY, etc. $(".open-filter").click(function (event) { event.stopPropagation(); var filterType = $(this).closest(".filter").data("filter"); var cardSelector = $(".card").length > 0 ? ".card" : ".community-card"; // Determine which card type is present console.log("Filter type:", filterType, "Card Selector:", cardSelector); $("#values-" + filterType).toggle(); if ($("#values-" + filterType).is(":visible")) { $(this).addClass("active-filter"); } else { $(this).removeClass("active-filter"); } // Pass the determined card selector to the function updateLastVisibleCard(cardSelector); updateWidthBlockView(cardSelector); processEventCards(cardSelector); updateViews(cardSelector); console.log("Updated views and borders after filter toggle"); }); function filterCards() { var displayCountsHtml = ""; var cardSelector = $(".card").length > 0 ? ".card" : ".community-card"; // Determine which card type is present $(".filter .values a[title]").each(function () { var anchor = $(this); var filterValue = anchor.attr("title").toLowerCase(); var count = 0; if (anchor.find("button").hasClass("active")) { $(cardSelector).each(function () { var card = $(this); $(".filter").each(function () { var filterType = $(this).data("filter"); var cardValue = card .find("." + filterType) .text() .toLowerCase(); if (cardValue.indexOf(filterValue) !== -1) { count++; } }); }); displayCountsHtml += "<span>[" + count + "] " + filterValue + "</span> "; } }); if (displayCountsHtml) { $(".count-filtered-cards").html(displayCountsHtml).show(); } else { $(".count-filtered-cards").hide(); } // Apply filtering and pass the determined card selector to the function applyFiltering(cardSelector); updateLastVisibleCard(cardSelector); updateWidthBlockView(cardSelector); processEventCards(cardSelector); updateViews(cardSelector); console.log("Filtering process complete, updated views and borders"); } function applyFiltering() { // Determine which card selector to use based on the elements present in the DOM var cardSelector = $(".card").length > 0 ? ".card" : ".community-card"; // Apply the logic to the determined card type $(cardSelector) .show() .each(function () { var card = $(this); var hideCard = false; $(".filter").each(function () { if (hideCard) return; var filterType = $(this).data("filter"); var activeFilters = $(this) .find(".values a[title] button.active") .map(function () { return $(this).parent("a").attr("title").toLowerCase(); }) .get(); if (activeFilters.length > 0) { var cardValue = card .find("." + filterType) .text() .toLowerCase(); var matchesFilter = activeFilters.some(function (filterValue) { return cardValue.indexOf(filterValue) !== -1; }); if (!matchesFilter) hideCard = true; } }); if (hideCard) card.hide(); }); } function updateLastVisibleCard() { // Target only the list view container for updating the last visible card $(".home-chronicle-list div.list-container div.card").removeClass( "last-visible" ); // Find the last visible card within the list view and add the class var lastVisibleCard = $( ".home-chronicle-list div.list-container div.card:visible:last" ); lastVisibleCard.addClass("last-visible"); } function updateWidthBlockView() { // Target only the block view container for updating the with of card $(".home-chronicle-block div.list-container").css("width", "100%"); $(".home-chronicle-block div.list-container div.card").css( "width", "calc(20% - 0px)" ); $( ".home-chronicle-block div.list-container div.card:nth-child(5n + 1)" ).css("width", "calc(20% + 4px)"); } // Reset function to remove active filters $(".reset-filter").click(function (event) { event.stopPropagation(); // Prevent event bubbling // Remove 'active' class from all filter buttons $("#filters .values button").removeClass("active"); $(".open-filter").removeClass("active-filter"); // Reset and hide the filter counts $(".count-filtered-cards").text("").hide(); filterCards(); // Reapply filtering based on the updated active buttons // Update other UI elements as needed, excluding the general toggle button updateLastVisibleCard(); updateWidthBlockView(); processEventCards(); updateViews(); }); $("#filters .values button").click(function () { console.log("Filter is clicked!!!"); $(this).toggleClass("active"); filterCards(); // Re-apply the filters based on the updated active buttons updateLastVisibleCard(); updateWidthBlockView(); processEventCards(); updateViews(); }); // Hide filters when window is scrolled $(window).on("scroll", function () { var filtersDiv = $("#filters"); if (filtersDiv.hasClass("is-visible")) { filtersDiv.removeClass("is-visible").slideUp(100, function () { $(this).css("display", "none"); // The filter reset code has been removed to keep the filters active }); $(".general-toggle").text("[FILTER]"); // Update the toggle button text } }); // MODAL ARTICLE --------------------- SECTION // // Format paragraphs function formatParagraphs(text) { var paragraphs = text.split("\n").filter(function (p) { return p.trim() !== ""; }); return paragraphs .map(function (p) { return "<p>" + p.trim() + "</p>"; }) .join(""); } var images = []; // Initialize an empty array to store the images // Find all image containers within the article content and extract the necessary information $(".article-images .image-container").each(function () { var img = $(this).find("img"); var captionDiv = $(this).find('div[class^="caption-image"]'); var image = { src: img.attr("src"), alt: img.attr("alt"), caption: captionDiv.text(), captionClass: captionDiv.attr("class"), }; images.push(image); // Add the image object to the images array }); if (images.length > 0) { setupImageToggle(images); // Call the setupImageToggle function with the images array updateImageLabel(1, images.length); // Set the label for the first image immediately } function setupImageToggle(images) { var currentIndex = 0; var enableNavigation = images.length > 1; // Enable navigation only if there is more than one image function showImage(index) { currentIndex = index; var image = images[currentIndex]; updateImageLabel(currentIndex + 1, images.length); $("#article-content") .find(".article-images") .html( getImageHtml(image, currentIndex, images.length, enableNavigation) ); } // Attach click handlers only if navigation is enabled if (enableNavigation) { $("#article-content").on("click", ".next-arrow", function () { showImage((currentIndex + 1) % images.length); }); $("#article-content").on("click", ".prev-arrow", function () { showImage((currentIndex - 1 + images.length) % images.length); }); } // Display the first image showImage(currentIndex); } function getImageHtml(image, currentIndex, totalImages, enableNavigation) { var imageLabel = currentIndex + 1 + "/" + totalImages + " IMAGES"; // Render navigation arrows based on the enableNavigation flag var navigationHtml = enableNavigation ? '<div class="prev-arrow"><</div><div class="next-arrow">></div>' : ""; return ( '<div class="image-navigation">' + '<p class="article-label-image">' + imageLabel + "</p>" + '<div class="image-container">' + '<div class="arrows-and-image">' + navigationHtml + '<img src="' + image.src + '" alt="' + image.alt + '">' + "</div>" + '<div class="' + image.captionClass + '">' + image.caption + "</div>" + "</div>" + "</div>" ); } function updateImageLabel(currentIndex, totalImages) { var imageLabel = currentIndex + "/" + totalImages + " IMAGES"; $("#article-content .article-label-image").text(imageLabel); } $(".caption-image1").each(function () { // Split the caption at each <br> tag and wrap each line in a span var htmlContent = $(this).html(); var lines = htmlContent.split("<br>"); var wrappedLines = lines.map(function (line) { return '<span class="caption-line">' + line + "</span>"; }); var newHtml = wrappedLines.join("<br>"); $(this).html(newHtml); }); function setShowArticleRotationEffect() { const offset = 20; const showArticle = document.querySelector("#show-article"); const h = showArticle.clientHeight; const theta = -Math.atan(offset / h); const a = Math.cos(theta); const b = Math.sin(theta); const c = -Math.sin(theta); const d = Math.cos(theta); const showArticleBefore = document.querySelector("#show-article-before"); const transformValue = "matrix(" + a + "," + b + "," + c + "," + d + ",0,0)"; showArticleBefore.style.transform = transformValue; } function openEvent(element, event) { event.stopPropagation(); event.preventDefault(); var url = $(element).find(".link a").attr("href"); if (url) { window.open(url, "_blank").focus(); } } function openModal(cardElement, event) { event.stopPropagation(); var pageTitle = $(cardElement).data("page") || null; // e.g. "090" window.currentEntryTitle = pageTitle; var isRelatedArticle = $(cardElement).hasClass("related-article"); showArticleWrapper.css("display", "block"); // Clear existing content in modal $("#article-title").empty(); $("#article-content").empty(); if (isRelatedArticle) { // Handle card elements (existing logic) var cardImages = []; for (var i = 1; i <= 5; i++) { var imageClass = ".related-article-image" + i; var captionClass = ".related-article-caption-image" + i; var imageElem = $(cardElement).find(imageClass + " img"); if (imageElem.length) { var captionText = $(cardElement) .find(imageClass + " " + captionClass) .text(); cardImages.push({ link: $(cardElement) .find(imageClass + " a") .attr("href"), src: imageElem.attr("src"), alt: imageElem.attr("alt"), caption: captionText, captionClass: "related-article-caption-image" + i, }); } } if (cardImages.length > 1) { setupImageToggle(cardImages); } // Handle related-article elements var entryNumber = $(cardElement) .find(".related-article-entry-number") .text(); var peopleHtml = $(cardElement).find(".related-article-people").html(); var title = $(cardElement).find(".related-article-title").text(); var typeHtml = $(cardElement).find(".related-article-type").html(); var externalPdfURL = $(cardElement) .find(".related-article-pdf a") .attr("href"); var externalLinkURL = $(cardElement) .find(".related-article-link a") .attr("href"); var entity = $(cardElement).find(".related-article-entity").text(); var discipline = $(cardElement) .find(".related-article-discipline") .text(); var subjectHtml = $(cardElement).find(".related-article-subject").html(); var description = $(cardElement) .find(".related-article-description") .html(); var reflection = $(cardElement) .find(".related-article-reflection") .html(); var quote = $(cardElement).find(".related-article-quote").text(); var modificationDate = $(cardElement) .find(".related-article-modification-date") .text(); // Update modal content for related-article $("#article-title").html( '<p class="article-entry-number">' + entryNumber + '</p><p class="article-people">' + peopleHtml + "</p>" ); var articleContentHtml = '<div class="article-title-link">'; articleContentHtml += '<p class="article-title">' + title + "</p>"; // Create a div that will wrap the links articleContentHtml += '<div class="link-pdf">'; if (externalPdfURL) { articleContentHtml += '<a href="' + externalPdfURL + '" target="_blank" class="pdf-link-icon">[PDF<span class="text-symbol">⤴</span>]</a>'; } if (externalLinkURL) { articleContentHtml += '<a href="' + externalLinkURL + '" target="_blank" class="external-link-icon">[WEB<span class="text-symbol">⤴</span>]</a>'; } // Close the .link-pdf div articleContentHtml += "</div>"; articleContentHtml += "</div>"; // Close the container div // Append type, entity, discipline, and subject details articleContentHtml += '<p class="article-type">' + typeHtml + "</p>" + '<div class="article-metadata">' + '<div class="article-metadata-column">' + '<p class="article-metadata-label">Entity</p>' + '<p class="article-metadata-value">' + entity + "</p>" + "</div>" + '<div class="article-metadata-column">' + '<p class="article-metadata-label">Discipline</p>' + '<p class="article-metadata-value">' + discipline + "</p>" + "</div>" + '<div class="article-metadata-column">' + '<p class="article-metadata-label">Subject(s)</p>' + '<p class="article-metadata-value">' + subjectHtml + "</p>" + "</div>" + "</div>"; // Add images if any if (cardImages.length > 0) { var initialImage = cardImages[0]; // Use the first image initially var enableNavigation = cardImages.length > 1; // Enable navigation only if more than one image articleContentHtml += '<div class="article-images">' + getImageHtml(initialImage, 0, cardImages.length, enableNavigation) + "</div>"; } // Add non-image content (description, reflection, etc.) articleContentHtml += (description ? '<p class="article-label-description">Description</p>' + '<div class="article-description">' + formatParagraphs(description) + "</div>" : "") + (reflection ? '<p class="article-label-reflection">Reflection</p>' + '<div class="article-reflection">' + formatParagraphs(reflection) + "</div>" : "") + (quote ? '<p class="article-label-quote">Quote</p>' + '<p class="article-quote">' + quote + "</p>" : "") + '<p class="article-label-modification-date">Added on</p>' + '<div class="article-modification-date">' + modificationDate + "</div>"; $("#article-content").html(articleContentHtml); } else { // Handle card elements (existing logic) var cardImages = []; for (var i = 1; i <= 5; i++) { var imageClass = ".image" + i; var captionClass = ".caption-image" + i; var imageElem = $(cardElement).find(imageClass + " img"); if (imageElem.length) { var captionText = $(cardElement) .find(imageClass + " " + captionClass) .text(); cardImages.push({ link: $(cardElement) .find(imageClass + " a") .attr("href"), src: imageElem.attr("src"), alt: imageElem.attr("alt"), caption: captionText, captionClass: "caption-image" + i, }); } } if (cardImages.length > 1) { setupImageToggle(cardImages); } var entryNumber = $(cardElement).find(".entry-number").text(); var title = $(cardElement).find(".title").text(); var peopleHtml = $(cardElement).find(".people").html(); var typeHtml = $(cardElement).find(".type").html(); var externalPdfURL = $(cardElement).find(".pdf a").attr("href"); var externalLinkURL = $(cardElement).find(".link a").attr("href"); var entity = $(cardElement).find(".entity").text(); var discipline = $(cardElement).find(".discipline").text(); var subjectHtml = $(cardElement).find(".subject").html(); var description = $(cardElement).find(".description").html(); var reflection = $(cardElement).find(".reflection").html(); var quote = $(cardElement).find(".quote").text(); var externalReferenceHtml = $(cardElement) .find(".external-reference") .html(); var modificationDate = $(cardElement).find(".modification-date").text(); var relatedArticlesHtml = $(cardElement).find(".related-articles").html(); $("#article-title").html( '<p class="article-entry-number">' + entryNumber + '</p><p class="article-people">' + peopleHtml + "</p>" ); var articleContentHtml = '<div class="article-title-link">'; articleContentHtml += '<p class="article-title">' + title + "</p>"; // Create a div that will wrap the links articleContentHtml += '<div class="link-pdf">'; if (externalPdfURL) { articleContentHtml += '<a href="' + externalPdfURL + '" target="_blank" class="pdf-link-icon">[PDF<span class="text-symbol">⤴</span>]</a>'; } if (externalLinkURL) { articleContentHtml += '<a href="' + externalLinkURL + '" target="_blank" class="external-link-icon">[WEB<span class="text-symbol">⤴</span>]</a>'; } // Close the .link-pdf div articleContentHtml += "</div>"; articleContentHtml += "</div>"; // Close the new div // Append type, entity, discipline, and subject details articleContentHtml += '<p class="article-type">' + typeHtml + "</p>" + '<div class="article-metadata">' + '<div class="article-metadata-column">' + '<p class="article-metadata-label">Entity</p>' + '<p class="article-metadata-value">' + entity + "</p>" + "</div>" + '<div class="article-metadata-column">' + '<p class="article-metadata-label">Discipline</p>' + '<p class="article-metadata-value">' + discipline + "</p>" + "</div>" + '<div class="article-metadata-column">' + '<p class="article-metadata-label">Subject(s)</p>' + '<p class="article-metadata-value">' + subjectHtml + "</p>" + "</div>" + "</div>"; // Add images if any if (cardImages.length > 0) { var initialImage = cardImages[0]; // Use the first image initially var enableNavigation = cardImages.length > 1; // Enable navigation only if more than one image articleContentHtml += '<div class="article-images">' + getImageHtml(initialImage, 0, cardImages.length, enableNavigation) + "</div>"; } // Add non-image content (description, reflection, etc.) articleContentHtml += (description ? '<p class="article-label-description">Description</p>' + '<div class="article-description">' + formatParagraphs(description) + "</div>" : "") + (reflection ? '<p class="article-label-reflection">Reflection</p>' + '<div class="article-reflection">' + formatParagraphs(reflection) + "</div>" : "") + (externalReferenceHtml ? '<p class="article-label-external-reference">References</p>' + '<p class="article-external-reference">' + externalReferenceHtml + "</p>" : "") + (quote ? '<p class="article-label-quote">Quote</p>' + '<p class="article-quote">' + quote + "</p>" : "") + '<p class="article-label-modification-date">Added on</p>' + '<div class="article-modification-date">' + modificationDate + "</div>"; $("#article-content").html(articleContentHtml); $("#related-articles").html(relatedArticlesHtml); if (relatedArticlesHtml && relatedArticlesHtml.trim().length > 0) { $("#related-articles") .html( '<div class="related-articles-label">Related Articles</div><div class="related-articles-container">' + relatedArticlesHtml + "</div>" ) .show(); } } // Check which view is active and set the width accordingly if ($(".home-chronicle-list").is(":visible")) { $(".home-list-view").each(function () { var currentWidth = $(this).width(); // Get the current width $(this).data("originalWidth", currentWidth); // Store the original width $(this).css("width", "calc(60% - 2px)"); }); // Modify the .type elements within .home-chronicle-list $(".home-chronicle-list .type").each(function () { var currentLeft = $(this).css("left"); // Get the current left value $(this).data("originalLeft", currentLeft); // Store the original left value $(this).css("left", "85%"); }); } else if ($(".home-chronicle-block").is(":visible")) { $(".home-chronicle-block div.list-container").each(function () { var currentWidth = $(this).width(); // Get the current width $(this).css("width", "calc(60% - 0px)"); // Set the new width as 30% of the current width }); $(".home-chronicle-block div.list-container div.card").each(function () { var currentWidth = $(this).width(); // Get the current width $(this).css("width", "calc(33.333% - 0px)"); // Set the new width as 30% of the current width }); } // Apply the fade-out effect to both #list and #list-list elements $(".list-container").addClass("fade-out"); } // closeModal function function closeModal() { 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(); var title = window.currentEntryTitle; // e.g. "090" if (!title) { console.warn("[print] no currentEntryTitle"); window.print(); $btn.data("busy", false); return; } var pageUrl = mw.util.getUrl(title); var pageUrlFresh = cacheBust(pageUrl); console.log("[print] fetching page HTML:", pageUrlFresh); $.get(pageUrlFresh) .done(function (html) { var $tmp = $("<div>").html(html); var $print = $tmp.find(".print-only").first(); console.log("[print] .print-only found:", $print.length); if (!$print.length) { console.warn("[print] no .print-only found; fallback print"); window.print(); $btn.data("busy", false); return; } // 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); var doc = iframe.contentDocument || iframe.contentWindow.document; doc.open(); doc.write( '<!doctype html><html><head><meta charset="utf-8"><title>Print</title></head><body></body></html>' ); doc.close(); // Ensure relative URLs (fonts/images) resolve inside iframe var base = doc.createElement("base"); base.href = location.origin + "/"; doc.head.appendChild(base); // Inject PRINT CSS (cache-busted) and await it 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; 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("link"); linkFont.rel = "preload"; linkFont.as = "font"; linkFont.type = "font/woff2"; linkFont.href = "/fonts/HALColant-TextRegular.woff2?v=20250820"; linkFont.crossOrigin = "anonymous"; doc.head.appendChild(linkFont); doc.head.appendChild(linkCss); // Inject the printable HTML doc.body.innerHTML = $print.prop("outerHTML"); // Wait helpers 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) { if (!doc.fonts || !doc.fonts.ready) return Promise.resolve(); var ready = doc.fonts.ready; var t = new Promise(function (res) { setTimeout(res, timeoutMs || 1200); }); return Promise.race([ready, t]); } // **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() { 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([ cssLoaded, waitImages(), waitFonts(1200), waitSpecificFont(1200), 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 ($(".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 if (encounteredTitles[title]) { // Hide the duplicate search result $(this).hide(); } else { // Mark the title as encountered encounteredTitles[title] = true; } }); // Remove unwanted white spaces between lines $(".mw-search-results-container") .contents() .filter(function () { return this.nodeType === 3; // Filter text nodes }) .remove(); // Edits regarding Search Results // Define the new form HTML as a string var newFormHtml = '<form action="/index.php" id="searchform">' + '<div id="simpleSearchSpecial" class="right-inner-addon">' + "<span>[ Search ]</span>" + '<input class="form-control" name="search" placeholder="" title="Search [alt-shift-f]" accesskey="f" id="searchInput" tabindex="1" autocomplete="off" type="search">' + '<span class="closing-bracket">]</span>' + '<input value="Special:Search" name="title" type="hidden">' + "</div>" + "</form>"; // Replace the div with id="searchText" with the new form $("#searchText").replaceWith(newFormHtml); // Target the button based on its complex class structure $(".oo-ui-actionFieldLayout-button .oo-ui-buttonInputWidget").remove(); // Check if #submit button exists and add event listener if it does var submitButton = document.querySelector("#submit"); 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); }); } }); });