MediaWiki:Common.js: Unterschied zwischen den Versionen
Admin (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung Markierung: Zurückgesetzt |
Admin (Diskussion | Beiträge) Keine Bearbeitungszusammenfassung Markierung: Manuelle Zurücksetzung |
||
| Zeile 220: | Zeile 220: | ||
/* Whisky-Ratings – eigenes Frontend für RatePage (Variante B) */ | |||
mw.loader.using(['mediawiki.api', 'mediawiki.user']).then(function () { | |||
function init() { | |||
document.querySelectorAll('.whisky-rating__item').forEach(setupWidget); | |||
} | |||
const | function setupWidget(box) { | ||
const pageTitle = box.dataset.ratepageTitle; | |||
const contest = box.dataset.ratepageContest || undefined; | |||
const scale = parseInt(box.dataset.ratepageScale || '10', 10); | |||
const widget = box.querySelector('.whisky-rating__widget'); | |||
const meta = box.querySelector('.whisky-rating__meta'); | |||
const | |||
const isAnon = mw.user.isAnon(); | |||
if (isAnon) { | if (isAnon) { | ||
box.classList.add('whisky-rating--disabled'); | |||
meta.textContent = 'Bitte einloggen, um zu bewerten.'; | |||
} | } | ||
// Buttons bauen | |||
const buttons = []; | |||
for (let i = 1; i <= scale; i++) { | |||
const btn = document.createElement('button'); | |||
btn.type = 'button'; | |||
btn.className = 'whisky-glass'; | |||
btn.setAttribute('aria-label', i + ' von ' + scale); | |||
btn.setAttribute('aria-pressed', 'false'); | |||
if (isAnon) { | |||
btn.disabled = true; | |||
btn.title = 'Nur für registrierte Benutzer'; | |||
} else { | |||
btn.title = i + ' / ' + scale; | |||
}); | btn.addEventListener('mouseenter', () => highlight(i)); | ||
btn.addEventListener('mouseleave', () => highlight(current)); | |||
btn.addEventListener('click', () => vote(i)); | |||
btn.addEventListener('keydown', (e) => { | |||
if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); vote(i); } | |||
if (e.key === 'ArrowRight' && i < scale) buttons[i].focus(); | |||
if (e.key === 'ArrowLeft' && i > 1) buttons[i-2].focus(); | |||
}); | |||
} | |||
widget.appendChild(btn); | |||
buttons.push(btn); | |||
} | |||
let current = 0; | |||
highlight(current); | |||
function highlight(n) { | |||
buttons.forEach((b, idx) => { | |||
const active = (idx < n); | |||
b.classList.toggle('is-active', active); | |||
b.setAttribute('aria-pressed', active ? 'true' : 'false'); | |||
}); | |||
} | |||
function vote(value) { | |||
const api = new mw.Api(); | |||
meta.textContent = 'Wird gespeichert …'; | |||
// | api.postWithToken('csrf', { | ||
action: 'ratepage', | |||
pagetitle: pageTitle, // Seitentitel, z. B. "Lagavulin 16" | |||
answer: value, // 1..10 | |||
contest: contest, // "NASE" | "GESCHMACK" | "ABGANG" | |||
format: 'json' | |||
}).done(function (data) { | |||
current = value; | |||
highlight(current); | |||
meta.textContent = 'Danke! Deine Bewertung: ' + value + ' / ' + scale; | |||
} | // Tipp: Wenn du später Durchschnitt/Anzahl anzeigen willst, | ||
// kannst du hier einen zusätzlichen API-Call einbauen, | |||
// sofern du die Stats von RatePage abrufen möchtest. | |||
}).fail(function (err) { | |||
console.error(err); | |||
meta.textContent = 'Speichern fehlgeschlagen. Bitte später erneut versuchen.'; | |||
}); | |||
} | |||
} | } | ||
// - | // Warten bis der DOM da ist (auch bei VisualEditor-Nachladungen) | ||
if (document.readyState === 'loading') { | |||
document.addEventListener('DOMContentLoaded', init); | |||
} else { | |||
init(); | |||
} | } | ||
}); | |||