MediaWiki:Common.js: Unterschied zwischen den Versionen

Keine Bearbeitungszusammenfassung
Markierung: Zurückgesetzt
Keine Bearbeitungszusammenfassung
Markierung: Zurückgesetzt
Zeile 219: Zeile 219:




/* ADOS Whisky-Ratings – RatePage Frontend (robust + Stats + Summary, ohne Optional Chaining) */
/* ADOS Whisky-Ratings – RatePage Frontend (ultra-kompatibel: ES3/ES5 only) */
mw.loader.using(['mediawiki.api', 'mediawiki.user']).then(function () {
mw.loader.using(['mediawiki.api', 'mediawiki.user']).then(function () {


   // ---------- Hilfsfunktionen ----------
   // ---- kleines get()-Hilfswerkzeug ohne ?. ----
   function get(obj, pathArray) {
   function get(obj, path) {
     var cur = obj;
     var cur = obj, i;
     for (var i = 0; i < pathArray.length; i++) {
     for (i = 0; i < path.length; i++) {
       if (!cur || typeof cur !== 'object') return undefined;
       if (!cur || typeof cur !== 'object') return undefined;
       cur = cur[pathArray[i]];
       cur = cur[path[i]];
     }
     }
     return cur;
     return cur;
   }
   }


   // ---------- Initialisierung ----------
   // ---- Bootstrapping ----
   function boot(root) {
   function boot(root) {
     var scope = root || document;
     var scope = root || document;
     var items = scope.querySelectorAll('.whisky-rating__item');
     var i, nodes;
    for (var i = 0; i < items.length; i++) setupWidget(items[i]);


     var summaries = scope.querySelectorAll('[data-ratepage-summary="true"]');
     nodes = scope.querySelectorAll('.whisky-rating__item');
     for (i = 0; i < summaries.length; i++) renderSummary(summaries[i]);
     for (i = 0; i < nodes.length; i++) setupWidget(nodes[i]);


     var metaOnly = scope.querySelectorAll('.whisky-rating__meta-only');
     nodes = scope.querySelectorAll('[data-ratepage-summary="true"]');
     for (i = 0; i < metaOnly.length; i++) renderMetaOnly(metaOnly[i]);
    for (i = 0; i < nodes.length; i++) renderSummary(nodes[i]);
 
    nodes = scope.querySelectorAll('.whisky-rating__meta-only');
     for (i = 0; i < nodes.length; i++) renderMetaOnly(nodes[i]);
   }
   }


Zeile 251: Zeile 253:
   }
   }


   mw.hook('wikipage.content').add(function($content) {
  // Achtung: $content ist jQuery – wir nehmen das rohe DOM-Element
   mw.hook('wikipage.content').add(function($content){
     if ($content && $content[0]) boot($content[0]);
     if ($content && $content[0]) boot($content[0]);
   });
   });


   // ---------- Widget (Gläser) ----------
   // ---- Widget (Gläser) ----
   function setupWidget(box) {
   function setupWidget(box) {
     var pageId  = mw.config.get('wgArticleId');
     var pageId  = mw.config.get('wgArticleId');
Zeile 270: Zeile 273:
     }
     }


    // Buttons bauen
     var buttons = [];
     var buttons = [];
     for (var i = 1; i <= scale; i++) {
    var i;
     for (i = 1; i <= scale; i++) {
       (function(iVal){
       (function(iVal){
         var btn = document.createElement('button');
         var btn = document.createElement('button');
Zeile 303: Zeile 306:


     function highlight(n) {
     function highlight(n) {
       for (var j = 0; j < buttons.length; j++) {
      var j;
       for (j = 0; j < buttons.length; j++) {
         var active = (j < n);
         var active = (j < n);
         buttons[j].classList.toggle('is-active', active);
         buttons[j].classList.toggle('is-active', active);
Zeile 310: Zeile 314:
     }
     }


    // Stats laden (Ø & Stimmen, eigene Stimme, canVote/see)
     function updateStats() {
     function updateStats() {
       var api = new mw.Api();
       var api = new mw.Api();
Zeile 322: Zeile 325:
         try {
         try {
           var pages = get(data, ['query','pages']) || {};
           var pages = get(data, ['query','pages']) || {};
           var pid = Object.keys(pages)[0];
           var keys = [];
          for (var k in pages) if (Object.prototype.hasOwnProperty.call(pages, k)) keys.push(k);
          var pid = keys.length ? keys[0] : String(pageId);
           var page = pages[pid] || {};
           var page = pages[pid] || {};
           var pr = page.pagerating;
           var pr = page.pagerating;
Zeile 338: Zeile 343:
             var hist = pr.pageRating || {};
             var hist = pr.pageRating || {};
             var total = 0, sum = 0;
             var total = 0, sum = 0;
             Object.keys(hist).forEach(function(k){
             for (var key in hist) {
              var s = parseInt(k, 10), c = parseInt(hist[k], 10);
              if (Object.prototype.hasOwnProperty.call(hist, key)) {
              if (!isNaN(s) && !isNaN(c)) { total += c; sum += s * c; }
                var s = parseInt(key, 10), c = parseInt(hist[key], 10);
             });
                if (!isNaN(s) && !isNaN(c)) { total += c; sum += s * c; }
              }
             }
             meta.textContent = total
             meta.textContent = total
               ? ('Ø ' + (Math.round((sum/total)*10)/10) + ' (' + total + ' Stimmen)')
               ? ('Ø ' + (Math.round((sum/total)*10)/10) + ' (' + total + ' Stimmen)')
Zeile 355: Zeile 362:
             box.classList.add('whisky-rating--disabled');
             box.classList.add('whisky-rating--disabled');
             var gls = widget.querySelectorAll('.whisky-glass');
             var gls = widget.querySelectorAll('.whisky-glass');
             for (var k = 0; k < gls.length; k++) gls[k].disabled = true;
             for (var i2 = 0; i2 < gls.length; i2++) gls[i2].disabled = true;
             if (!/nicht abstimmen/.test(meta.textContent)) {
             if (meta.textContent.indexOf('nicht abstimmen') === -1) {
               meta.textContent += (meta.textContent ? ' • ' : '') + 'Du darfst hier nicht abstimmen.';
               meta.textContent += (meta.textContent ? ' • ' : '') + 'Du darfst hier nicht abstimmen.';
             }
             }
           }
           }
         } catch (e) {
         } catch (e) {
           console.error(e);
           if (window.console && console.error) console.error(e);
           if (meta && !meta.textContent) meta.textContent = 'Bewertungen konnten nicht geladen werden.';
           if (meta && !meta.textContent) meta.textContent = 'Bewertungen konnten nicht geladen werden.';
         }
         }
       }).fail(function (xhr) {
       }).fail(function (xhr) {
         console.error('Pagerating-Load-Error', xhr);
         if (window.console && console.error) console.error('Pagerating-Load-Error', xhr);
         if (meta && !meta.textContent) meta.textContent = 'Bewertungen konnten nicht geladen werden.';
         if (meta && !meta.textContent) meta.textContent = 'Bewertungen konnten nicht geladen werden.';
       });
       });
     }
     }


    // Vote senden
     function vote(value) {
     function vote(value) {
       var api = new mw.Api();
       var api = new mw.Api();
Zeile 402: Zeile 408:
           }
           }
         } catch(e){}
         } catch(e){}
         console.error('RatePage-API-Fehler:', xhr);
         if (window.console && console.error) console.error('RatePage-API-Fehler:', xhr);
         if (meta) meta.textContent = 'Speichern fehlgeschlagen: ' + msg;
         if (meta) meta.textContent = 'Speichern fehlgeschlagen: ' + msg;
       });
       });
Zeile 410: Zeile 416:
   }
   }


   // ---------- Meta-only Ø für einzelne Kategorien ----------
   // ---- Meta-only Ø (einzelne Kategorie irgendwo im Text) ----
   function renderMetaOnly(box) {
   function renderMetaOnly(box) {
     var pageId = parseInt(box.dataset.ratepagePageid || mw.config.get('wgArticleId'), 10);
     var pageId = parseInt(box.dataset.ratepagePageid || mw.config.get('wgArticleId'), 10);
Zeile 422: Zeile 428:
     }).done(function (data) {
     }).done(function (data) {
       var pages = get(data, ['query','pages']) || {};
       var pages = get(data, ['query','pages']) || {};
       var pid = Object.keys(pages)[0];
       var keys = [];
      for (var k in pages) if (Object.prototype.hasOwnProperty.call(pages, k)) keys.push(k);
      var pid = keys.length ? keys[0] : String(pageId);
       var pr = pages[pid] && pages[pid].pagerating;
       var pr = pages[pid] && pages[pid].pagerating;
       if (!pr) { box.textContent = ''; return; }
       if (!pr) { box.textContent = ''; return; }
Zeile 428: Zeile 436:
       var hist = pr.pageRating || {};
       var hist = pr.pageRating || {};
       var total = 0, sum = 0;
       var total = 0, sum = 0;
       Object.keys(hist).forEach(function(k){
       for (var key in hist) {
        var s = +k, c = +hist[k];
        if (Object.prototype.hasOwnProperty.call(hist, key)) {
        if (s && c) { total += c; sum += s * c; }
          var s = Number(key), c = Number(hist[key]);
       });
          if (s && c) { total += c; sum += s * c; }
        }
       }
       box.textContent = total ? ('Ø ' + (Math.round((sum/total)*10)/10) + ' (' + total + ' Stimmen)') : 'Noch keine Bewertungen';
       box.textContent = total ? ('Ø ' + (Math.round((sum/total)*10)/10) + ' (' + total + ' Stimmen)') : 'Noch keine Bewertungen';
     });
     });
   }
   }


   // ---------- Kompakte Ø-Tabelle oben ----------
   // ---- Kompakte Ø-Tabelle oben (NASE/GESCHMACK/ABGANG) ----
   function renderSummary(container) {
   function renderSummary(container) {
     var pageId  = mw.config.get('wgArticleId');
     var pageId  = mw.config.get('wgArticleId');
     var contests = (container.dataset.ratepageContests || 'NASE,GESCHMACK,ABGANG')
     var raw = container.dataset.ratepageContests || 'NASE,GESCHMACK,ABGANG';
                      .split(',');
    var contests = raw.split(',');
     for (var i = 0; i < contests.length; i++) contests[i] = contests[i].trim();
    var i;
     for (i = 0; i < contests.length; i++) contests[i] = contests[i].replace(/^\s+|\s+$/g, '');
     contests = contests.filter(function(s){ return !!s; });
     contests = contests.filter(function(s){ return !!s; });


Zeile 456: Zeile 467:
       }).then(function (data) {
       }).then(function (data) {
         var pages = get(data, ['query','pages']) || {};
         var pages = get(data, ['query','pages']) || {};
         var pid = Object.keys(pages)[0];
         var keys = [];
        for (var k in pages) if (Object.prototype.hasOwnProperty.call(pages, k)) keys.push(k);
        var pid = keys.length ? keys[0] : String(pageId);
         var pr = pages[pid] && pages[pid].pagerating;
         var pr = pages[pid] && pages[pid].pagerating;
         if (!pr || (typeof pr.canSee !== 'undefined' && pr.canSee === 0)) {
         if (!pr || (typeof pr.canSee !== 'undefined' && pr.canSee === 0)) {
Zeile 463: Zeile 476:
         var hist = pr.pageRating || {};
         var hist = pr.pageRating || {};
         var total = 0, sum = 0;
         var total = 0, sum = 0;
         Object.keys(hist).forEach(function(k){
         for (var key in hist) {
          var s = +k, c = +hist[k];
          if (Object.prototype.hasOwnProperty.call(hist, key)) {
          if (s && c) { total += c; sum += s * c; }
            var s = Number(key), c = Number(hist[key]);
         });
            if (s && c) { total += c; sum += s * c; }
          }
         }
         var avg = total ? Math.round((sum / total) * 10) / 10 : null;
         var avg = total ? Math.round((sum / total) * 10) / 10 : null;
         return { contest: contest, total: total, avg: avg, label: labels[contest] || contest };
         return { contest: contest, total: total, avg: avg, label: labels[contest] || contest };
Zeile 472: Zeile 487:
     }
     }


     Promise.all(contests.map(fetchContest)).then(function (rows) {
     var promises = [];
    for (i = 0; i < contests.length; i++) promises.push(fetchContest(contests[i]));
 
    Promise.all(promises).then(function (rows) {
       var table = document.createElement('table');
       var table = document.createElement('table');
       table.className = 'whisky-summary__table';
       table.className = 'whisky-summary__table';
Zeile 483: Zeile 501:
       for (var r = 0; r < rows.length; r++) {
       for (var r = 0; r < rows.length; r++) {
         var row = rows[r];
         var row = rows[r];
         var avgText = (row.avg !== null) ? row.avg.toFixed(1) : '–';
         var avgText = (row.avg !== null) ? (row.avg.toFixed ? row.avg.toFixed(1) : (Math.round(row.avg*10)/10)) : '–';
         var totalText = row.total ? String(row.total) : '0';
         var totalText = row.total ? String(row.total) : '0';
         var tr = document.createElement('tr');
         var tr = document.createElement('tr');
Zeile 491: Zeile 509:
       table.appendChild(tbody);
       table.appendChild(tbody);


       container.replaceChildren(table);
      // replaceChildren ist relativ neu – wir nehmen fallback
      while (container.firstChild) container.removeChild(container.firstChild);
       container.appendChild(table);
     });
     });
   }
   }


});
});