Benutzer:Schnark/js/watchlisttags.js

aus Wikipedia, der freien Enzyklopädie
Zur Navigation springen Zur Suche springen

Hinweis: Leere nach dem Veröffentlichen den Browser-Cache, um die Änderungen sehen zu können.

  • Firefox/Safari: Umschalttaste drücken und gleichzeitig Aktualisieren anklicken oder entweder Strg+F5 oder Strg+R (⌘+R auf dem Mac) drücken
  • Google Chrome: Umschalttaste+Strg+R (⌘+Umschalttaste+R auf dem Mac) drücken
  • Edge: Strg+F5 drücken oder Strg drücken und gleichzeitig Aktualisieren anklicken
//Dokumentation unter [[Benutzer:Schnark/js/watchlisttags]] <nowiki>
mw.libs.deprecated = $.extend(mw.libs.deprecated, {watchlisttags: 'Das Skript [[Benutzer:Schnark/js/watchlisttags]] wird nicht mehr gepflegt. Für die meisten Anwender ist [[Benutzer:Schnark/js/watchlist++]] ein sehr guter Ersatz. Du kannst dieses Skript natürlich auch weiterhin verwenden, aber falls Fehler auftreten, werden diese nicht mehr behoben.'});
importScript('Benutzer:Schnark/js/deprecated.js');

/*global mw: true */
/*jshint bitwise: false */
(function($){

var watchlisttags = {
version: 1.14,

key: '/ / / schnarkwatchlisttags', //Schlüssel, der an Seite angehängt wird, Leerzeichen sind nötig
bits: 4, //Anzahl der Bits, die gespeichert werden
escape: function(name) {
 return encodeURIComponent(name).replace(/([.%!*'()])/g, function (x) {return '.' + x.charCodeAt(0);});
},
main: function(title) {
 var ns = mw.config.get('wgFormattedNamespaces'), i;
 for (i in ns) {
     if (i !== '-2' && i !== '-1' && i % 2 === 1 && title.indexOf(ns[i] + ':') === 0) {
         return title.replace(ns[i], ns[i - 1]).replace(/^:/, '');
     }
 }
 return title;
},
canonical: function(title) {
 if (title.indexOf(':') === -1) {
    return title;
 }
 var title_parts = title.split(':'), ns = mw.config.get('wgNamespaceIds')[title_parts[0].toLowerCase().replace(/ /g, '_')];
 if (ns !== undefined) {
    title_parts[0] = mw.config.get('wgFormattedNamespaces')[ns.toString()];
 }
 return title_parts.join(':');
},

userinterface: { //Variablen für Interface
 sd: ['S+D', 'S', 'D'], //Seite und Diskussion, nur Seite, nur Diskussion
 tags: ['(kein Stichwort)', 'offene Frage', 'Vandalismus', 'interessant', 'nützlich'], //3*n <= 2^bits
 control: function(name, value) { //liefert das Einstellwerkzeug für eine Seite mit einem Startwert
   var i, $control,
       htmlname = 'watchlisttags-' + watchlisttags.escape(name) + '-sd',
       html = '<span class="watchlisttags-control">';
   for (i = 0; i < 3; i++) {
       html += mw.html.element('input', {type: 'radio', name: htmlname, id: htmlname + i, value: i}) +
               mw.html.element('label', {'for': htmlname + i}, watchlisttags.userinterface.sd[i]);
   }
   html += '<select name="watchlisttags-' + watchlisttags.escape(name) + '-tags">';
   for (i = 0; i < watchlisttags.userinterface.tags.length; i++) {
       html += mw.html.element('option', {value: i}, watchlisttags.userinterface.tags[i]);
   }
   html += '</select></span>';
   $control = $(html);
   $control.find(':radio[value="' + (value % 3) + '"]').prop('checked', true);
   $control.find('select option[value="' + Math.floor(value / 3) + '"]').prop('selected', true);
   $control.attr('rel', name);
   $control.find(':radio').on('change', {page: name}, watchlisttags.userinterface.onchange);
   $control.find('select').on('change', {page: name}, watchlisttags.userinterface.onchange);
   $control.click(function(e){e.stopPropagation();}); //sonst wird Bubble geschlossen
   return $control;
 },
 onchange: function(ev) { //onchange-Handler für control
   var name = ev.data.page,
       $control = $('.watchlisttags-control[rel="' + name.replace(/"/g, '\\"') + '"]');
   watchlisttags.set(name, Number($control.find(':radio:checked').val()) + $control.find('select :selected').val() * 3);
 }
},

//Hilfsvariablen für API-Abfrage
callback: {
 c: null, //übergebene Callback-Funktion
 n: 0, //Anzahl der Einzelabfragen
 list: {}, //'Seite': Wert
 f: function (json) { //Callback-Funktion
  watchlisttags.callback.n--;
  if (json && json.query && json.query.pages) {
     var pages = json.query.pages, p, a, title;
     for (p in pages) {
         if (pages.hasOwnProperty(p) && pages[p].watched === '') {
            a = pages[p].title.split(watchlisttags.key);
            title = watchlisttags.canonical(a[0]);
            if (watchlisttags.callback.list[title] === undefined) {
               watchlisttags.callback.list[title] = 0;
            }
            watchlisttags.callback.list[title] += Math.pow(2, a[1]);
         }
     }
  }
  if (watchlisttags.callback.n === 0) {
     watchlisttags.callback.c(watchlisttags.callback.list);
  }
 },
 f_err: function () { //Callback-Funktion für Fehler
   watchlisttags.callback.f(false);
 }
},

/* Holt Informationen zu den Titeln
 * titles: Array mit Titeln
 * callback: Funktion, wird mit {'Titel': wert, ...} aufgerufen
 */
get: function(titles, callback) {
   var i, j, all = [];
   for (i = 0; i < titles.length; i++) {
       for (j = 0; j < watchlisttags.bits; j++) {
           all.push(titles[i] + watchlisttags.key + j);
       }
   }
   watchlisttags.callback.c = callback;
   watchlisttags.callback.n = Math.ceil(all.length / 50);
   for (i = 1; i < watchlisttags.callback.n; i++) {
       $.ajax({type: 'POST', dataType: 'json',
               url: mw.util.wikiScript('api'),
               data: {action: 'query', prop: 'info', inprop: 'watched',
                      titles: all.splice(0, 50).join('|'), format: 'json' },
               success: watchlisttags.callback.f, error: watchlisttags.callback.f_err
              });
   }
   $.ajax({type: 'POST', dataType: 'json',
           url: mw.util.wikiScript('api'),
           data: {action: 'query', prop: 'info', inprop: 'watched',
                  titles: all.join('|'), format: 'json' },
           success: watchlisttags.callback.f, error: watchlisttags.callback.f_err
          });
   },
set: function(title, value) {
   var i, data;
   for (i = 0; i < watchlisttags.bits; i++) {
       data = {action: 'watch', title: title + watchlisttags.key + i, token: mw.user.tokens.get('watchToken'), format: 'json'};
       if (((value >> i) & 1) === 0) {
          data.unwatch = '';
       }
       $.post(mw.util.wikiScript('api'), data);
   }
},

watchlist: { //auf der Beobachtungsliste
 init: function() {
    //Checkboxen einfügen
    var $checkboxes = $('<div>'),
        i, selector, name, $check, title,
        titles = [], unique_titles = [],
        func = function (ev) {
                  if ($(this).prop('checked')) {
                     $(ev.data.selector).show();
                  } else {
                     $(ev.data.selector).hide();
                  }
               };
    $('#mw-watchlist-options').append($checkboxes);
    for (i = 0; i < watchlisttags.userinterface.tags.length; i++) {
        selector = '.watchlisttags-tag' + i;
        name = 'wlt-chkbox-' + i;
        $check = $(mw.html.element('input', {id: name, name: name, type: 'checkbox', checked: true}))
                  .on('click', {selector: selector}, func);
        $checkboxes.append($check);
        $checkboxes.append(mw.html.element('label', {'for': name}, watchlisttags.userinterface.tags[i]));
    }

    $('table.mw-enhanced-rc, ul.special li').each(function() {
     //enhanced              normal
          titles.push($(this).find('.mw-title a').attr('title') || $(this).find('a.new').text() || '');
    });
    for (i = 0; i < titles.length; i++) {
        title = watchlisttags.main(titles[i]);
        if (title !== '' && $.inArray(title, unique_titles) === -1) {
           unique_titles.push(title);
        }
    }
    watchlisttags.get(unique_titles, watchlisttags.watchlist.mark);
 },
 mark: function(list) {
    $('table.mw-enhanced-rc, ul.special li').each(function() {
      var $item = $(this),
          title = watchlisttags.canonical($item.find('.mw-title a').attr('title') || $item.find('a.new').text() || ''),
          title_raw = watchlisttags.main(title),
          v = list[title_raw] || 0,
          sd = v % 3;
      v = Math.floor(v/3);
      if (sd === 1 && title !== title_raw) {
         $item.addClass('watchlisttags-unwanted-discussion');
      }
      if (sd === 2 && title === title_raw) {
         $item.addClass('watchlisttags-unwanted-page');
      }
      $item.addClass('watchlisttags-tag' + v);
    });
 }
},

watchlistedit: { //beim Bearbeiten der Beobachtungsliste
 init: function() {
   var $last_item, last_title, last_removed, value;
   $('div.mw-htmlform-flatlist-item').each(function() { //TODO: evt. eachAsync
     var $item = $(this), title, a;
     if ($item.find('input[type="checkbox"]').length === 0) {
        return;
     }
     title = $item.find('a').eq(0).text();
     if (title.indexOf(watchlisttags.key) === -1) { //ohne key: für vorherigen Control einfügen, merken
        if ($last_item !== undefined) {
           $last_item.append(watchlisttags.userinterface.control(last_title, value));
        }
        $last_item = $item;
        last_title = title;
        value = 0;
     } else {
        a = title.split(watchlisttags.key);
        if (a[0] === last_title) { //mit key, bekannt: Wert erhöhen
           value += Math.pow(2, a[1]);
        } else { //mit key, unbekannt: beim ersten set(0)
           if (a[0] !== last_removed) {
              watchlisttags.set(a[0], 0);
              last_removed = a[0];
           }
        }
        $item.remove();
     }
     });
     if ($last_item !== undefined) {
        $last_item.append(watchlisttags.userinterface.control(last_title, value));
     }
 }
},

watch: { //beim Beobachten von Seiten
 init: function() {
   var pageName = mw.config.get('wgRelevantPageName') || mw.config.get('wgPageName'),
       $box = $('.mw-notification-tag-watch-self .mw-notification-content'); //beim Beobachten mit AJAX
   if ($box.length === 0) { //ohne AJAX
      $box = $('p:has(.selflink)');
   }
   if ($box.length === 0) {
      return;
   }
   if ($box.hasClass('watchlisttags-ajax-started')) {
      return;
   }
   $box.addClass('watchlisttags-ajax-started');
   watchlisttags.get([pageName], function (list) {
     var v = list[pageName] || 0;
     $box.append(watchlisttags.userinterface.control(pageName, v));
   });
 }
},

init: function() {
  if (mw.config.get('wgCanonicalSpecialPageName') === 'Watchlist') {
     watchlisttags.watchlist.init();
  }
  if (mw.config.get('wgCanonicalSpecialPageName') === 'EditWatchlist' && location.href.indexOf('/raw') === -1) {
     watchlisttags.watchlistedit.init();
  }
  if (mw.config.get('wgAction') === 'watch') {
     watchlisttags.watch.init();
  }
  if (mw.config.get('wgNamespaceNumber') >= 0) {
     $('#content').on('mouseenter', '.mw-notification-tag-watch-self', watchlisttags.watch.init);
     $('#mw-js-message').on('mouseenter', watchlisttags.watch.init); //deprecated
  }
}

};

if (mw.config.get('debug')) {window.watchlisttags = watchlisttags;}
$(document).trigger('loadWikiScript', ['Benutzer:Schnark/js/watchlisttags.js', watchlisttags]);
mw.loader.using(['user.options', 'mediawiki.util'], function () {
   $(watchlisttags.init);
});
})(jQuery);
//</nowiki>