Common.js: Difference between revisions
From Illustrations in German Translations of Mark Twain's Works
No edit summary |
No edit summary |
||
| Line 440: | Line 440: | ||
newTab.document.close(); | newTab.document.close(); | ||
} | } | ||
// =============================== | |||
// Zusatz: MediaInfo abrufen & anzeigen | |||
// =============================== | |||
// MediaInfo aus API laden | |||
async function fetchMediaInfo(filename) { | |||
const apiUrl = '/api.php?action=query&prop=revisions&titles=File:' + encodeURIComponent(filename) + '&rvprop=content&format=json'; | |||
try { | |||
const response = await fetch(apiUrl); | |||
const data = await response.json(); | |||
// Wikitext der Seite extrahieren | |||
const pages = data.query.pages; | |||
const page = pages[Object.keys(pages)[0]]; | |||
if (!page.revisions) return null; | |||
const wikitext = page.revisions[0]['*'] || page.revisions[0]['slots']?.main['*']; | |||
if (!wikitext) return null; | |||
// MediaInfo-Block herausziehen | |||
const match = wikitext.match(/\{\{MediaInfo([\s\S]*?)\}\}/); | |||
if (!match) return null; | |||
const block = match[1]; | |||
// Werte in Objekt parsen | |||
const info = {}; | |||
const fields = ["title","chapter","illustration","illustrator","year","tags","publication"]; | |||
fields.forEach(field => { | |||
const regex = new RegExp("\\|\\s*" + field + "\\s*=([^\\n]*)"); | |||
const m = block.match(regex); | |||
if (m) info[field] = m[1].trim(); | |||
}); | |||
return info; | |||
} catch (err) { | |||
console.error("Fehler beim Laden der MediaInfo:", err); | |||
return null; | |||
} | |||
} | |||
// MediaInfo im passenden Textfeld anzeigen | |||
async function showMediaInfo(target, filename) { | |||
const infoBox = document.getElementById('mediainfo' + target); | |||
if (!infoBox) return; | |||
infoBox.textContent = "Lade Informationen..."; | |||
const info = await fetchMediaInfo(filename); | |||
if (!info) { | |||
infoBox.textContent = "Keine Informationen gefunden."; | |||
return; | |||
} | |||
let html = "<ul style='margin:0; padding-left:1em'>"; | |||
for (const [key, value] of Object.entries(info)) { | |||
html += "<li><b>" + key + ":</b> " + value + "</li>"; | |||
} | |||
html += "</ul>"; | |||
infoBox.innerHTML = html; | |||
} | |||
// Chapter Script | // Chapter Script | ||
Revision as of 14:22, 16 September 2025
/* Any JavaScript here will be loaded for all users on every page load. */
mw.loader.using('jquery').then(function () {
console.log('jQuery ist verfügbar:', typeof $);
$.getScript('https://cdn.datatables.net/1.13.6/js/jquery.dataTables.min.js')
.then(() => {
console.log('DataTables geladen:', $.fn.dataTable);
return $.getScript('https://cdn.datatables.net/datetime/1.5.1/js/dataTables.dateTime.min.js');
})
.then(() => $.getScript('https://cdn.datatables.net/searchbuilder/1.6.0/js/dataTables.searchBuilder.min.js'))
.then(() => {
console.log('DataTables + Erweiterungen geladen');
if ($.fn.dataTable && $.fn.dataTable.SearchBuilder) {
console.log('SearchBuilder:', $.fn.dataTable.SearchBuilder);
} else {
console.warn('SearchBuilder nicht verfügbar');
}
mw.hook('wikipage.content').add(function($content) {
const $table = $content.find('#catalog');
if ($table.length && !$.fn.DataTable.isDataTable($table)) {
$table.DataTable({
dom: 'Qlfrtip',
searchBuilder: true,
paging: true,
pageLength: 600,
searching: true,
ordering: true,
lengthMenu: [[10, 25, 50, 100, 200, 600], [10, 25, 50, 100, 200, 600]],
order: [[1, 'asc']],
language: {
search: "Search:",
lengthMenu: "Show _MENU_ Entries",
zeroRecords: "No Matches",
info: "Page _PAGE_ of _PAGES_ (showing _TOTAL_ of _MAX_ entries)",
infoEmpty: "Empty",
infoFiltered: ""
},
initComplete: function () {
this.api().columns().every(function () {
var column = this;
var header = $(column.header());
var columnTitle = header.text();
$('<input type="text" placeholder="' + columnTitle + ' ..." style="width: 100%; padding: 5px;"/>')
.appendTo(header.empty())
.on('keyup change', function () {
column.search(this.value).draw();
})
.on('click', function (e) {
e.stopPropagation();
});
});
}
});
}
});
})
.catch((err) => {
console.error('Fehler beim Laden von DataTables oder Erweiterungen:', err);
});
});
/*AUSKLAPPMENÜS*/
$(function () {
$('.ausklapp-button').click(function () {
var $button = $(this);
var $content = $button.next('.ausklapp-inhalt');
$content.slideToggle(200);
var expanded = $button.attr('aria-expanded') === 'true';
$button.attr('aria-expanded', !expanded);
});
});
// Hover-Preview für Bild-Links in DataTables
$(document).ready(function() {
// Neuen Image-Container einfügen
$('body').append('<div id="image-hover-preview" style="display:none; position:absolute; z-index:9999;"><img src="" style="max-width:400px; max-height:400px; border:1px solid #ccc; background:white; padding:5px;"></div>');
// Auf alle Links in der Tabelle achten
$('#catalog').on('mouseenter', 'a', function(e) {
var href = $(this).attr('href');
if (href && href.includes('/Special:Redirect/file/')) {
var imgUrl = href; // URL direkt verwenden
$('#image-hover-preview img').attr('src', imgUrl);
$('#image-hover-preview').show();
}
}).on('mousemove', 'a', function(e) {
$('#image-hover-preview').css({
top: e.pageY + 20 + 'px',
left: e.pageX + 20 + 'px'
});
}).on('mouseleave', 'a', function() {
$('#image-hover-preview').hide();
});
});
$(document).ready(function () {
const searchButton = document.getElementById('searchButton');
const tagInput = document.getElementById('tagInput');
if (searchButton && tagInput) {
searchButton.addEventListener('click', function () {
const tags = tagInput.value.split(',').map(tag => tag.trim());
searchImagesByTags(tags);
});
} else {
console.warn('searchButton oder tagInput nicht gefunden.');
}
});
function searchImagesByTags(tags) {
var url = new URL(window.location.href);
var apiUrl = url.origin + '/w/api.php';
// Hier wird eine Anfrage an die MediaWiki API gestellt, um nach Bildern zu suchen, die den Tags entsprechen
fetch(`${apiUrl}?action=query&format=json&list=categorymembers&cmtitle=Category:${tags.join('&cmtitle=Category:')}&cmtype=file`)
.then(response => response.json())
.then(data => {
var images = data.query.categorymembers;
displayImages(images);
})
.catch(error => console.error('Error:', error));
}
function displayImages(images) {
var galleryContainer = document.getElementById('galleryContainer');
galleryContainer.innerHTML = ''; // Leere den Container, um Platz für neue Bilder zu schaffen
// Überprüfe, ob Bilder vorhanden sind
if (images.length === 0) {
galleryContainer.innerHTML = '<p>No images found.</p>';
return;
}
// Bilder in die Galerie einfügen
images.forEach(image => {
var imgElement = document.createElement('img');
imgElement.src = '/index.php/Special:Redirect/file/' + image.title.replace('Category:', '');
imgElement.alt = image.title;
galleryContainer.appendChild(imgElement);
});
}
// Funktion zur Extraktion der Dateinamen aus der Tabelle und zur Anzeige in der Galerie
function updateGalleryFromTable() {
// Tabelle durchsuchen und Dateinamen extrahieren
var rows = document.querySelectorAll('#catalog tbody tr');
var imageLinks = [];
rows.forEach(row => {
var imageCell = row.cells[8]; // Die 9. Zelle enthält den Dateinamen als Link
var link = imageCell.querySelector('a'); // Link innerhalb der Zelle
if (link) {
var imageName = link.textContent.trim(); // Der Text des Links ist der Dateiname
var imageUrl = '/index.php/Special:Redirect/file/' + imageName + '.jpg';
imageLinks.push(imageUrl);
}
});
// Neue Seite mit Galerie öffnen
var galleryWindow = window.open('', '_blank');
if (galleryWindow) {
galleryWindow.document.write('<html><head><title>Gallery</title>');
galleryWindow.document.write('<style>');
galleryWindow.document.write('body { font-family: sans-serif; padding: 20px; }');
galleryWindow.document.write('img { max-width: 300px; margin: 10px; cursor: pointer; display: inline-block; }');
galleryWindow.document.write('</style></head><body>');
galleryWindow.document.write('<h2>Results</h2>');
imageLinks.forEach(url => {
galleryWindow.document.write('<img src="' + url + '" onclick="window.open(\'' + url + '\')">');
});
galleryWindow.document.write('</body></html>');
galleryWindow.document.close();
} else {
alert('Popup wurde blockiert. Bitte erlaube Popups für diese Seite.');
}
}
$(document).ready(function () {
const columnCount = 9;
// Neue Bedingung hinzufügen
$('#addCondition').on('click', function () {
const newRow = $('<div class="search-row" style="margin-bottom: 5px;">' +
'<select class="bool-select">' +
'<option value="AND">AND</option>' +
'<option value="OR">OR</option>' +
'<option value="NOT">NOT</option>' +
'<option value="XOR">XOR</option>' +
'</select>' +
'<select class="field-select">' +
'<option value="8">ID</option>' +
'<option value="all">All</option>' +
'<option value="0">Book</option>' +
'<option value="1">Year</option>' +
'<option value="2">Illustrator</option>' +
'<option value="3">Chpt in Orig</option>' +
'<option value="4">Chpt in this Ed.</option>' +
'<option value="5">Ill. in Chpt.</option>' +
'<option value="6">Illustration Title</option>' +
'<option value="7">Tags</option>' +
'</select>' +
'<input type="text" class="search-input" placeholder=" ">' +
'<button class="remove-condition" style="margin-left: 5px;">🗑️</button>' +
'</div>');
$('#searchConditions').append(newRow);
});
// Dynamisch hinzugefügte Bedingungen löschen
$('#searchConditions').on('click', '.remove-condition', function () {
if ($('#searchConditions .search-row').not('.fixed').length > 1) {
$(this).closest('.search-row').remove();
}
});
// Suche ausführen
$('#runAdvancedSearch').on('click', function () {
const table = $('#catalog').DataTable();
table.search('').columns().search('');
const filters = [];
// 1. Feste erste Bedingung einfügen
filters.push({
column: '8', // ID-Spalte
term: 'hf',
boolOp: null
});
// 2. Alle weiteren Bedingungen
$('#searchConditions .search-row').not('.fixed').each(function () {
const column = $(this).find('.field-select').val();
const term = $(this).find('.search-input').val().trim();
const boolOp = $(this).find('.bool-select').val();
if (term !== '') {
filters.push({ column, term, boolOp });
}
});
if (filters.length === 0) {
table.draw();
return;
}
// Filterlogik
$.fn.dataTable.ext.search = [];
$.fn.dataTable.ext.search.push(function (settings, data, dataIndex) {
let result = null;
filters.forEach(function (filter, i) {
const val = filter.column === 'all'
? data.join(' ').toLowerCase()
: (data[filter.column] || '').toLowerCase();
const match = val.includes(filter.term.toLowerCase());
if (i === 0) {
result = match;
} else {
switch (filter.boolOp) {
case 'AND': result = result && match; break;
case 'OR': result = result || match; break;
case 'NOT': result = result && !match; break;
case 'XOR': result = (result && !match) || (!result && match); break;
}
}
});
return result;
});
table.draw();
});
});
// ===============================
// Comparison / Slideshow Script
// ===============================
// Gefilterte Bild-Links aus DataTable holen
function getFilteredImageLinks() {
var rows = document.querySelectorAll('#catalog tbody tr');
var images = [];
rows.forEach(row => {
// Nur sichtbare Zeilen (durch DataTables-Filter!) berücksichtigen
if (row.style.display !== 'none') {
var imageCell = row.cells[8];
var link = imageCell ? imageCell.querySelector('a') : null;
if (link) {
var imageName = link.textContent.trim();
var imageUrl = '/index.php/Special:Redirect/file/' + imageName + '.jpg';
images.push({
url: imageUrl, // echte Bilddatei (für Slideshow)
name: imageName + '.jpg' // Dateiname (für File:-Link)
});
}
}
});
return images;
}
// Globale Slideshow-Objekte
const slideshows = {
A: { images: [], index: 0 },
B: { images: [], index: 0 },
C: { images: [], index: 0 },
D: { images: [], index: 0 },
};
// Counter-Update
function updateCounter(target) {
const data = slideshows[target];
const total = data.images.length;
const current = total > 0 ? data.index + 1 : 0; // Index ist 0-basiert
const counterEl = document.getElementById("counter" + target);
if (counterEl) {
counterEl.textContent = current + "/" + total;
}
}
// Bildanzeige
function updateSlide(target) {
const data = slideshows[target];
const imgElement = document.getElementById('slide' + target);
if (data.images.length === 0) {
imgElement.src = '';
imgElement.alt = 'No Images';
imgElement.onclick = null;
updateCounter(target);
// Info leeren
const infoBox = document.getElementById('mediainfo' + target);
if (infoBox) infoBox.textContent = "";
return;
}
if (data.index < 0) data.index = data.images.length - 1;
if (data.index >= data.images.length) data.index = 0;
const currentImage = data.images[data.index];
imgElement.src = currentImage.url;
imgElement.alt = currentImage.name;
imgElement.style.cursor = "pointer";
imgElement.onclick = function () {
window.open('/File:' + currentImage.name, '_blank');
};
updateCounter(target);
// Neue Info laden
showMediaInfo(target, currentImage.name);
}
// Slideshow initial befüllen
function populateSlideshow(target) {
const images = getFilteredImageLinks();
slideshows[target].images = images;
slideshows[target].index = 0;
const imgElement = document.getElementById('slide' + target);
if (images.length > 0) {
imgElement.src = images[0].url;
imgElement.alt = images[0].name;
imgElement.style.cursor = "pointer";
imgElement.onclick = function () {
window.open('/File:' + images[0].name, '_blank');
};
} else {
imgElement.src = '';
imgElement.alt = 'No Images';
imgElement.onclick = null;
}
// Counter sofort aktualisieren
updateCounter(target);
}
// Buttons
function nextSlideX(target) {
slideshows[target].index++;
updateSlide(target);
}
function prevSlideX(target) {
slideshows[target].index--;
updateSlide(target);
}
// Neue Seite mit allen Bildern öffnen
function openSlideshowInNewTab(target) {
const data = slideshows[target];
if (!data.images || data.images.length === 0) {
alert("No images to display for slideshow " + target);
return;
}
const newTab = window.open();
if (!newTab) {
alert("Popup blocked! Bitte Popups für diese Seite erlauben.");
return;
}
let html = "<html><head><title>Slideshow " + target + "</title></head><body style='font-family:sans-serif'>";
html += "<h2>Slideshow " + target + " (" + data.images.length + " images)</h2>";
html += "<div style='display:flex; flex-wrap:wrap; gap:10px;'>";
data.images.forEach(img => {
html += "<div>";
html += "<a href='/File:" + img.name + "' target='_blank'>";
html += "<img src='" + img.url + "' style='max-width:300px; height:auto;'>";
html += "</a></div>";
});
html += "</div></body></html>";
newTab.document.open();
newTab.document.write(html);
newTab.document.close();
}
// ===============================
// Zusatz: MediaInfo abrufen & anzeigen
// ===============================
// MediaInfo aus API laden
async function fetchMediaInfo(filename) {
const apiUrl = '/api.php?action=query&prop=revisions&titles=File:' + encodeURIComponent(filename) + '&rvprop=content&format=json';
try {
const response = await fetch(apiUrl);
const data = await response.json();
// Wikitext der Seite extrahieren
const pages = data.query.pages;
const page = pages[Object.keys(pages)[0]];
if (!page.revisions) return null;
const wikitext = page.revisions[0]['*'] || page.revisions[0]['slots']?.main['*'];
if (!wikitext) return null;
// MediaInfo-Block herausziehen
const match = wikitext.match(/\{\{MediaInfo([\s\S]*?)\}\}/);
if (!match) return null;
const block = match[1];
// Werte in Objekt parsen
const info = {};
const fields = ["title","chapter","illustration","illustrator","year","tags","publication"];
fields.forEach(field => {
const regex = new RegExp("\\|\\s*" + field + "\\s*=([^\\n]*)");
const m = block.match(regex);
if (m) info[field] = m[1].trim();
});
return info;
} catch (err) {
console.error("Fehler beim Laden der MediaInfo:", err);
return null;
}
}
// MediaInfo im passenden Textfeld anzeigen
async function showMediaInfo(target, filename) {
const infoBox = document.getElementById('mediainfo' + target);
if (!infoBox) return;
infoBox.textContent = "Lade Informationen...";
const info = await fetchMediaInfo(filename);
if (!info) {
infoBox.textContent = "Keine Informationen gefunden.";
return;
}
let html = "<ul style='margin:0; padding-left:1em'>";
for (const [key, value] of Object.entries(info)) {
html += "<li><b>" + key + ":</b> " + value + "</li>";
}
html += "</ul>";
infoBox.innerHTML = html;
}
// Chapter Script
importScript('MediaWiki:ChapterSlides.js');
// Chapter Script
importScript('MediaWiki:ChapterSlidesAlt.js');
// Filter Scripts, character pages
importScript('MediaWiki:CharacterFilter.js');
// CharacterDistribution
// Chart.js von CDN laden
mw.loader.load('https://cdn.jsdelivr.net/npm/chart.js');
// CharacterDistribution.js laden (klassischer Weg)
importScript('MediaWiki:CharacterDistribution.js');
// Media Viewer Adjustments to Display Title and Tags
importScript('MediaWiki:MediaViewerDisplay.js');
if (mw.config.get('wgPageName') === 'Wiki/chardist') {
// Chart.js von CDN laden
mw.loader.load('https://cdn.jsdelivr.net/npm/chart.js', function() {
document.addEventListener('DOMContentLoaded', () => {
const canvas = document.getElementById('testChart');
if (!canvas) return;
const ctx = canvas.getContext('2d');
new Chart(ctx, {
type: 'bar',
data: {
labels: ['A','B','C'],
datasets: [{
label: 'Test',
data: [1,2,3],
backgroundColor: 'red'
}]
},
options: {}
});
});
});
}