לדלג לתוכן

מדיה ויקי:Gadget-Cat-a-lot.js: הבדלים בין גרסאות בדף

מתוך צפונות ויקי
Undo revision 45808622 by DieBuche (talk)
אין תקציר עריכה
שורה 1: שורה 1:
// <source lang="javascript">
// <source lang="javascript">
// Variables
// Variables
var cat_a_lot_mark_color = "#3399FF" ;
var cat_a_lot_api_url = wgScriptPath + "/api.php" ;
var cat_a_lot_edit_url = wgScript + "?title=" ;
var cat_a_lot_divtype = 'div' ;
var cat_a_lot_classname = 'gallerytext' ;
var cat_a_lot_searchmode = false ;
var cat_a_lot_parent;
String.prototype.trim = function () {
String.prototype.trim = function () {
  return this.replace (/^\s+|\s+$/g, "");
return this.replace(/^\s+|\s+$/g, "");
}
};


String.prototype.ucFirst = function () {
String.prototype.ucFirst = function () {
  return this.substr(0,1).toUpperCase() + this.substr(1,this.length);
return this.substr(0, 1).toUpperCase() + this.substr(1, this.length);
}
};


String.prototype.lcFirst = function () {
String.prototype.lcFirst = function () {
  return this.substr(0,1).toLowerCase() + this.substr(1,this.length);
return this.substr(0, 1).toLowerCase() + this.substr(1, this.length);
}
};


String.prototype.replaceAll = function ( s , r ) {
String.prototype.replaceAll = function (s, r) {
  return this.split(s).join(r);
return this.split(s).join(r);
}
};


var catALot = {
apiUrl: wgScriptPath + "/api.php",
searchmode: false,


if ( wgNamespaceNumber == 14 ) {
  $j(document).ready ( init_cat_a_lot ) ;
}


if ( wgNamespaceNumber == -1 && wgCanonicalSpecialPageName == "Search" ) {
init_cat_a_lot: function () {
  cat_a_lot_divtype = 'table' ;
this.parent = document.getElementById("mw-category-media") || getElementsByClassName(document, "ul", "mw-search-results")[0];
  cat_a_lot_classname = 'searchResultImage' ;
if (!this.parent) return;
  cat_a_lot_searchmode = true ;
  $j(document).ready ( init_cat_a_lot ) ;
}


var c1_div = document.getElementById("column-one");
if (!c1_div) c1_div = document.getElementById("mw-panel");
if (!c1_div) return;
c1_div.innerHTML += '<div id="cat_a_lot">' + '<div id="cat_a_lot_data">' +


// Add this to URLs to get around cache issues
'<div>' + '<form name="cat_a_lot_searchcat" method="post" onSubmit="return false;">' + '<input type="text" input="8" name="cat_a_lot_searchcatname" />' + '<input type="submit" name="cat_a_lot_go" value="Go" onclick="cat_a_lot_search_cat();"/>' + '</form>' + '</div><div id="cat_a_lot_category_list"></div>' + '<div id="cat_a_lot_mark_counter"> </div>' + '<div id="cat_a_lot_selections" >Select <a href="#" id="cat_a_lot_select_all">all</a> / ' + '<a href="#" id="cat_a_lot_select_none">none</a>' + '</div>' + '<div>' + '<a href="#" onclick ="cat_a_lot_remove()"><b>Remove from this category</b></a>' + '</div>' + '<form name="cat_a_lot_edit" enctype="multipart/form-data" method="post" target="_blank">' + '<input type="hidden" name="wpTextbox1" />' + '<input type="hidden" name="wpSummary" />' + '<input type="hidden" name="wpDiff" value="wpDiff" />' + '<input type="hidden" name="wpStarttime" />' + '<input type="hidden" name="wpEdittime" />' + '</form>' + '</div>' + '<div id="cat_a_lot_head" class="pBody">' + '<form><input id="cat_a_lot_mode" type="checkbox" onchange="run_cat_a_lot();"/><label for="cat_a_lot_mode">Cat-a-lot mode</label></form>' + '</div></div>';
function cat_a_lot_dummy_time() {
  var t = new Date () ;
  return "&dummytime=" + t.getTime() ;
}


function init_cat_a_lot () {
$('#cat_a_lot_select_all').click(function () {
  cat_a_lot_parent = document.getElementById( "mw-category-media" ) || getElementsByClassName( document, "ul", "mw-search-results" )[0];
catALot.toggleAll(true);
  if( !cat_a_lot_parent) return;
});
$('#cat_a_lot_select_none').click(function () {
catALot.toggleAll(false);
});


  var c1_div = document.getElementById("column-one") ;
  if (!c1_div) c1_div = document.getElementById("mw-panel");
  if (!c1_div) return;
  c1_div.innerHTML += '<div id="cat_a_lot" style="z-index:9999;display:block;background-color:white; position:fixed; bottom:0; right:0;">' +
    '<div class="cat_a_lot_data" id="cat_a_lot_data" style="display:none;border:1px solid black">' +


    '<div style="border-bottom:1px solid black">' +
if (skin == "vector") appendCSS("#cat_a_lot {font-size: .75em};");
    '<form name="cat_a_lot_searchcat" method="post" onSubmit="return false;">' +
},
    '<input type="text" input="8" name="cat_a_lot_searchcatname" />' +
findAllLabels: function () {
    '<input type="submit" name="cat_a_lot_go" value="Go" onclick="cat_a_lot_search_cat();"/>' +
if (this.searchmode) this.labels = $('table.searchResultImage td:eq(1)');
    '</form>' +
else this.labels = $('div.gallerytext');
    '</div>' +
},


    '<div class="cat_a_lot_category_list" id="cat_a_lot_category_list" style="border-bottom:1px solid black;max-height:500px;overflow:auto"> </div>' +
getMarkedLabels: function () {
    '<div class="cat_a_lot_mark_counter" id="cat_a_lot_mark_counter"> </div>' +
var marked = [];
    '<div class="cat_a_lot_selections" id="cat_a_lot_selections" style="border-top:1px solid black">Select ' +
this.selectedLabels = this.labels.filter('.cat_a_lot_selected');
    '<a href="#" onClick="cat_a_lot_mark_all(' + "'2'" + ');">all</a> / ' +
this.selectedLabels.each(function () {
    '<a href="#" onClick="cat_a_lot_mark_all(' + "'3'" + ');">none</a>' +
var file = $(this).find('a[title]');
    '</div>' +
marked.push(file.attr('title'));
    '<div>' +
});
    '<a href="#" onclick ="cat_a_lot_remove()"><b>Remove from this category</b></a>' +
return marked;
    '</div>' +
},
    '<form name="cat_a_lot_edit" enctype="multipart/form-data" method="post" target="_blank">' +
    '<input type="hidden" name="wpTextbox1" />' +
    '<input type="hidden" name="wpSummary" />' +
    '<input type="hidden" name="wpDiff" value="wpDiff" />' +
    '<input type="hidden" name="wpStarttime" />' +
    '<input type="hidden" name="wpEdittime" />' +
    '</form>' +
    '</div>' +
    '<div id="cat_a_lot_head" class="pBody">' +
    '<form><input id="cat_a_lot_mode" type="checkbox" onchange="run_cat_a_lot();"/><label for="cat_a_lot_mode">Cat-a-lot mode</label></form>' +
    '</div></div>' ;
if( skin == "vector" )
  appendCSS( "#cat_a_lot {font-size: .75em};");
}


function cat_a_lot_get_marked_labels () {
updateSelectionCounter: function () {
  var ret = new Array () ;
this.selectedLabels = this.labels.filter('.cat_a_lot_selected');
  var divs = getElementsByClassName( cat_a_lot_parent, cat_a_lot_divtype, cat_a_lot_classname);
$('#cat_a_lot_mark_counter').html(this.selectedLabels.length + " files selected.");
  for ( var i = 0 ; i < divs.length ; i++ ) {
},
    if ( divs[i].style.backgroundColor == "" ) continue ;
    var files = divs[i].getElementsByTagName ( "a" ) ;
    var t = cat_a_lot_gettitle(files) ;
    ret.push ( t ) ;
  }
  return ret ;
}


function cat_a_lot_update_selection_counter () {
makeClickable: function () {
  var cat_a_lot_mark_counter = document.getElementById("cat_a_lot_mark_counter") ;
this.findAllLabels();
  var l = cat_a_lot_get_marked_labels () ;
this.labels.click(function () {
  cat_a_lot_mark_counter.innerHTML = l.length + " files selected." ;
$(this).toggleClass('cat_a_lot_selected');
}
this.updateSelectionCounter();
});
},
toggleAll: function (select) {


function cat_a_lot_on_click_label ( title ) {
this.labels.toggleClass('cat_a_lot_selected', select);
  cat_a_lot_alter_label ( title , "onclick" ) ;
this.updateSelectionCounter();
}
},


function cat_a_lot_invalidate_label ( title , mode ) {
get_subcategories: function () {
  cat_a_lot_alter_label ( title , mode ) ;
var data = {
}
action:'query',
list:'categorymembers',
cmnamespace:14,
cmlimit:50
cmtitle:'Category:'+this.current_category
};
this.doAPICall(data, function(result) {
//Process the return
// var cls = xml.getElementsByTagName('cm');
// var ret = new Array();
// for (var i = 0; i < cls.length; i++) {
// if (cls[i].getAttribute('ns') != 14) continue; // XXX: partial workaround for MW API bug (cmnamespace parameter doesn't work)
// var title = cls[i].getAttribute('title');
// title = title.split(":", 2)[1];
// ret.push(title);
// }
// return ret;


function cat_a_lot_alter_label ( title , mode ) {
});
  var divs = getElementsByClassName( cat_a_lot_parent, cat_a_lot_divtype, cat_a_lot_classname ) ;
},
  for ( var i = 0 ; i < divs.length ; i++ ) {
    var files = divs[i].getElementsByTagName ( "a" ) ;
    if ( files.length == 0 ) continue ;
    if ( cat_a_lot_gettitle(files) != title ) continue ;


    if ( mode == "move" ) {
get_parent_categories: function () {
      divs[i].innerHTML += "<div style=\"width:100%;color:white;background-color:red;text-align:center;\">Moved to new category</div>" ;
var data = {
      divs[i].style.backgroundColor = "#FF0000" ;
action:'query',
    } else if ( mode == "remove" ) {
prop:'categories',
      divs[i].innerHTML += "<div style=\"width:100%;color:white;background-color:red;text-align:center;\">Removed from category</div>" ;
titles:'Category:'+this.current_category
      divs[i].style.backgroundColor = "#FF0000" ;
};
    } else if ( mode == "copy" ) {
this.doAPICall(data, function(result) {
      divs[i].innerHTML += "<div style=\"width:100%;font-weight:bold;\">Copied to new category!</div>" ;
    }
var cls = xml.getElementsByTagName('cl');
var ret = new Array();
for (var i = 0; i < cls.length; i++) {
var title = cls[i].attributes.getNamedItem("title").value;
title = title.split(":", 2)[1];
ret.push(title);
}
return ret;


    // Clicked on this element
});
    if ( divs[i].style.backgroundColor != "" ) {
},
      divs[i].style.backgroundColor = "" ;
    } else {
      divs[i].style.backgroundColor = cat_a_lot_mark_color ;
    }
    cat_a_lot_update_selection_counter () ;
    return ;
  }
}


function cat_a_lot_fix_quotes ( text , quote ) {
replaceCategory: function (text, sourcecat, targetcat) {
  return text.split(quote).join("\\"+quote) ;
var re = new RegExp('\[\[Category:\s*' + catname + '\s*([\||\]\]])','ig');
}
return text.replace(re, '[[Category:'+targetcat+'$1');
},


function cat_a_lot_gettitle( files ) {
removeCategory: function (text, sourcecat) {
  var ret = "";
var re = new RegExp('\[\[Category:\s*' + catname + '\s*\]\]','ig');
  if( files.length > 0 ) {
return text.replace(re, '');
      var flag = ( cat_a_lot_searchmode && files.length > 1 ) ? 1 : 0;
},
      ret = files[flag].title;
      if( files[flag].originalTitle ) // navpopups mode
        ret = files[flag].originalTitle;
  }
  return ret;
}


function cat_a_lot_mark_all ( how ) {
edit_move: function (filename, targetcat, mode) {
  var divs = getElementsByClassName( cat_a_lot_parent, cat_a_lot_divtype, cat_a_lot_classname ) ;
var sourcecat = wgTitle;
  for ( var i = 0 ; i < divs.length ; i++ ) {
var url = this.edit_url + encodeURIComponent(filename) + "&action=raw" + this.dummy_time();
    var files = divs[i].getElementsByTagName ( "a" ) ;
var xmlreq = sajax_init_object();
    if ( files.length == 0 ) continue ;
xmlreq.open("GET", url, false);
xmlreq.send(null);
var otext = xmlreq.responseText.trim();


    divs[i].style.backgroundColor = "" ; // Deselect
// Check if that file is already in that category
    if ( how == 1 ) { // Activate
if (mode != "remove") {
      var title = cat_a_lot_gettitle( files );
if (otext.indexOf("ategory:" + targetcat.ucFirst()) != -1 || otext.indexOf("ategory:" + targetcat.lcFirst()) != -1) {
      if ( cat_a_lot_searchmode )
alert(filename + " is already in category " + targetcat + " - skipping.");
        divs[i] = divs[i].getElementsByTagName('div')[0] ;
return;
}
}


      eval("divs[i].onclick = function () { cat_a_lot_on_click_label('" + cat_a_lot_fix_quotes ( title , "'" ) + "'); };") ;
// Fix text
    } else if ( how == 2 ) { // Select
var text = otext;
      divs[i].style.backgroundColor = cat_a_lot_mark_color ;
if (mode == 'copy') {
    } else if ( how == 0 ) { // Deactivate
text += "\n[[" + "Category:" + targetcat + "]]\n";
      divs[i].onclick = "" ;
} else if (mode == 'move') {
    }
text = this.replaceCategory(text, sourcecat, targetcat);
  }
} else if (mode == 'remove') {
  cat_a_lot_update_selection_counter () ;
text = this.removeCategory();
}
}


function cat_a_lot_get_subcategories () {
if (text == otext) {
  var url = cat_a_lot_api_url + "?action=query&format=xml&list=categorymembers&cmnamespace=14&cmlimit=50&cmtitle=Category:" + encodeURIComponent (cat_a_lot_current_category) + cat_a_lot_dummy_time() ;
alert("Could not find an occurrence of category " + sourcecat + " in description of file " + filename + " - skipping.");
  var xmlreq = sajax_init_object() ;
return;
  xmlreq.open ( "GET" , url , false ) ;
}
  xmlreq.send ( null ) ;
  xml = xmlreq.responseXML ;
  var cls = xml.getElementsByTagName('cm') ;
  var ret = new Array () ;
  for ( var i = 0 ; i < cls.length ; i++ ) {
    if (cls[i].getAttribute('ns') != 14) continue;  // XXX: partial workaround for MW API bug (cmnamespace parameter doesn't work)
    var title = cls[i].getAttribute('title');
    title = title.split(":",2)[1] ;
    ret.push ( title ) ;
  }
  return ret ;
}


function cat_a_lot_get_parent_categories () {
var time = new Date();
  var url = cat_a_lot_api_url + "?action=query&format=xml&prop=categories&titles=Category:" + encodeURIComponent (cat_a_lot_current_category) + cat_a_lot_dummy_time() ;
  var xmlreq = sajax_init_object() ;
  xmlreq.open ( "GET" , url , false ) ;
  xmlreq.send ( null ) ;
  xml = xmlreq.responseXML ;
  var cls = xml.getElementsByTagName('cl') ;
  var ret = new Array () ;
  for ( var i = 0 ; i < cls.length ; i++ ) {
    var title = cls[i].attributes.getNamedItem("title").value ;
    title = title.split(":",2)[1] ;
    ret.push ( title ) ;
  }
  return ret ;
}


function cat_a_lot_replace_category ( text , sourcecat , targetcat , catname , ending ) {
var comment;
//  alert ( "[[" + catname + ":" + sourcecat + ending + " : " + "[[" + "Category:" + targetcat + ending ) ;
if (mode == "move") comment = "Moving from [[" + "Category:" + sourcecat + "]] to [[" + "Category:" + targetcat + "]]";
  return text.replaceAll ( "[[" + catname + ":" + sourcecat + ending , "[[" + "Category:" + targetcat + ending ) ;
if (mode == "copy") comment = "Copying from [[" + "Category:" + sourcecat + "]] to [[" + "Category:" + targetcat + "]]";
}
if (mode == "remove") comment = "Removing from [[" + "Category:" + sourcecat + "]]";
url = this.edit_url + encodeURIComponent(filename) + "&action=edit";
// document.this.edit.action = url;
// document.this.edit.wpSummary.value = comment;
// document.this.edit.wpTextbox1.value = text;
// document.this.edit.wpStarttime.value = starttime;
// document.this.edit.wpEdittime.value = last_version_timestamp;
// document.this.edit.submit();
this.alter_label(filename, mode);
},
alter_label: function (title, mode) {
var divs = getElementsByClassName(this.parent, this.divtype, this.classname);
for (var i = 0; i < divs.length; i++) {
var files = divs[i].getElementsByTagName("a");
if (files.length == 0) continue;
if (this.gettitle(files) != title) continue;


if (mode == "move") {
divs[i].innerHTML += "<div style=\"width:100%;color:white;background-color:red;text-align:center;\">Moved to new category</div>";
divs[i].style.backgroundColor = "#FF0000";
} else if (mode == "remove") {
divs[i].innerHTML += "<div style=\"width:100%;color:white;background-color:red;text-align:center;\">Removed from category</div>";
divs[i].style.backgroundColor = "#FF0000";
} else if (mode == "copy") {
divs[i].innerHTML += "<div style=\"width:100%;font-weight:bold;\">Copied to new category!</div>";
}


function cat_a_lot_fix_time ( time ) {
return;
  time = time.replace ( /:/g , "" ) ;
}
  time = time.replace ( / /g , "" ) ;
},
  time = time.replace ( /-/g , "" ) ;
move_here: function (targetcat) {
  time = time.replace ( /Z/g , "" ) ;
this.do_something(this.decode(targetcat), 'move');
  time = time.replace ( /T/g , "" ) ;
},
  return time ;
}


function cat_a_lot_get_article_timestamp ( title ) {
copy_here: function (targetcat) {
  var ret ;
this.do_something(this.decode(targetcat), 'copy');
  var url = cat_a_lot_api_url + '?action=query&format=xml&prop=revisions&rvprop=timestamp&titles=' + title ;
},


  var xmlreq = sajax_init_object() ;
remove: function () {
  xmlreq.open ( "GET" , url , false ) ;
this.do_something('', 'remove');
  xmlreq.send ( null ) ;
},
  var xml = xmlreq.responseXML ;
  var rev = xml.getElementsByTagName('rev') ;
  if ( rev.length == 0 ) return cat_a_lot_get_current_utc_timestamp () ;


  ret = rev.item(0).getAttribute('timestamp') ;
do_something: function (targetcat, mode) {
  ret = cat_a_lot_fix_time ( ret ) ;
var files = this.getMarkedLabels();
  return ret
if (files.length == 0) {
}
alert("No files selected.");
return;
}
for (var i = 0; i < files.length; i++) {
this.edit_move(files[i], targetcat, mode);
}
},


function cat_a_lot_remove_category ( text , sourcecat , cat , ending ) {
htmlize: function (str) {
  text = " " + text ;
return str.replace(/&/g, '&amp;').replace(/\xa0/g, '&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;') // " // Fix syntax coloring
  var parts = text.split ( "[[" + cat + ":" + sourcecat + ending ) ;
.replace(/\'/g, '&apos;') // ' // Fix syntax coloring
  if ( parts.length == 1 ) return text.trim() ; // Not found
;
  text = parts.shift () ;
},
  while ( parts.length > 0 ) {
    var s = parts.shift () ;
    if ( ending == "|" ) {
      var endOfLink = s.indexOf ("]]");
      if (endOfLink >= 0) s = s.substring (endOfLink + 2);
    }
    text += s ;
  }
  return text.trim() ;
}


function cat_a_lot_edit_move ( filename , targetcat , mode ) {
encode: function (str) {
  var sourcecat = wgTitle ;
return encodeURIComponent(str).replace(/'/g, '%27').replace(/"/g, '%22');
  var url = cat_a_lot_edit_url + encodeURIComponent (filename) + "&action=raw" + cat_a_lot_dummy_time() ;
},
  var xmlreq = sajax_init_object() ;
  xmlreq.open ( "GET" , url , false ) ;
  xmlreq.send ( null ) ;
  var otext = xmlreq.responseText.trim() ;


  // Check if that file is already in that category
decode: function (str) {
  if ( mode != "remove" ) {
return decodeURIComponent(str.replace(/%27/g, "'").replace(/%22/g, '"'));
    if ( otext.indexOf ( "ategory:" + targetcat.ucFirst() ) != -1 ||
},
        otext.indexOf ( "ategory:" + targetcat.lcFirst() ) != -1 ) {
      alert ( filename + " is already in category " + targetcat + " - skipping." ) ;
      return ;
    }
  }


  // Fix text
get_cat_links: function (symbol, list) {
  var text = otext ;
var ret = "";
  if ( mode == 'copy' ) {
list.sort();
    text += "\n[[" + "Category:" + targetcat + "]]\n" ;
for (var i = 0; i < list.length; i++) {
  } else if ( mode == 'move' ) {
ret += "<tr style='border:1px solid #AAAAAA'><td>" + symbol + "</td><td>";
    text = cat_a_lot_replace_category ( text , sourcecat.ucFirst() , targetcat , "category" , "]]" ) ;
ret += '<a href="#" onclick ="this.update_cats(\'' + this.encode(list[i]) + '\', true)">' + this.htmlize(list[i]) + '</a>';
    text = cat_a_lot_replace_category ( text , sourcecat.lcFirst() , targetcat , "category" , "]]" ) ;
ret += "</td><td>";
    text = cat_a_lot_replace_category ( text , sourcecat.ucFirst() , targetcat , "Category" , "]]" ) ;
if (list[i] != wgTitle) { // Can't move to source category
    text = cat_a_lot_replace_category ( text , sourcecat.lcFirst() , targetcat , "Category" , "]]" ) ;
ret += '<a href="#" onclick ="this.move_here(\'' + this.encode(list[i]) + '\')"><b>Move</b></a> ';
    text = cat_a_lot_replace_category ( text , sourcecat.ucFirst() , targetcat , "category" , "|" ) ;
ret += '<a href="#" onclick ="this.copy_here(\'' + this.encode(list[i]) + '\')"><b>Copy</b></a>';
    text = cat_a_lot_replace_category ( text , sourcecat.lcFirst() , targetcat , "category" , "|" ) ;
}
    text = cat_a_lot_replace_category ( text , sourcecat.ucFirst() , targetcat , "Category" , "|" ) ;
ret += "</td></tr>";
    text = cat_a_lot_replace_category ( text , sourcecat.lcFirst() , targetcat , "Category" , "|" ) ;
}
  } else if ( mode == 'remove' ) {
return ret;
    text = cat_a_lot_remove_category ( text , sourcecat.ucFirst() , "category" , "]]" ) ;
},
    text = cat_a_lot_remove_category ( text , sourcecat.lcFirst() , "category" , "]]" ) ;
    text = cat_a_lot_remove_category ( text , sourcecat.ucFirst() , "category" , "|" ) ;
    text = cat_a_lot_remove_category ( text , sourcecat.lcFirst() , "category" , "|" ) ;
    text = cat_a_lot_remove_category ( text , sourcecat.ucFirst() , "Category" , "]]" ) ;
    text = cat_a_lot_remove_category ( text , sourcecat.lcFirst() , "Category" , "]]" ) ;
    text = cat_a_lot_remove_category ( text , sourcecat.ucFirst() , "Category" , "|" ) ;
    text = cat_a_lot_remove_category ( text , sourcecat.lcFirst() , "Category" , "|" ) ;
  }


  if ( text == otext ) {
show_category_list: function () {
    alert ( "Could not find an occurrence of category " + sourcecat + " in description of file " + filename + " - skipping." ) ;
var parcats = this.get_parent_categories();
    return ;
var subcats = this.get_subcategories();
  }
var thiscat = new Array();
thiscat.push(this.current_category);


  var time = new Date () ;
var out = "<table border='0'>";
  var last_version_timestamp = cat_a_lot_get_article_timestamp ( filename ) ;
out += this.get_cat_links("&uarr;", parcats);
  var starttime = cat_a_lot_get_current_utc_timestamp () ;
out += this.get_cat_links("&rarr;", thiscat);
out += this.get_cat_links("&darr;", subcats);
out += "</table>";


  var comment ;
catlist = document.getElementById("this.category_list");
  if ( mode == "move" ) comment = "Moving from [[" + "Category:" + sourcecat + "]] to [[" + "Category:" + targetcat + "]]" ;
catlist.innerHTML = out;
  if ( mode == "copy" ) comment = "Copying from [[" + "Category:" + sourcecat + "]] to [[" + "Category:" + targetcat + "]]" ;
document.body.style.cursor = 'auto';
  if ( mode == "remove" ) comment = "Removing from [[" + "Category:" + sourcecat + "]]" ;
},
  url = cat_a_lot_edit_url + encodeURIComponent(filename) + "&action=edit" ;
  document.cat_a_lot_edit.action = url ;
  document.cat_a_lot_edit.wpSummary.value = comment ;
  document.cat_a_lot_edit.wpTextbox1.value = text ;
  document.cat_a_lot_edit.wpStarttime.value = starttime ;
  document.cat_a_lot_edit.wpEdittime.value = last_version_timestamp ;
  document.cat_a_lot_edit.submit () ;


  cat_a_lot_invalidate_label ( filename , mode ) ;
update_cats: function (newcat, encoded) {
}
document.body.style.cursor = 'wait';
if (encoded) newcat = this.decode(newcat);
this.current_category = newcat;
catlist = document.getElementById("this.category_list");
catlist.innerHTML = '<div style="background-color:red;color:white">Loading...</div>';
window.setTimeout("cat_a_lot_show_category_list()", 0);
},


// Generates current timestamp
search_cat: function () {
function cat_a_lot_get_current_utc_timestamp () {
//var newcat = document.this.searchcat.this.searchcatname.value;
  var today=new Date() ;  
this.update_cats(newcat);
},


  var y  = "00" + today.getUTCFullYear() ;
run_cat_a_lot: function () {
  var mo = today.getUTCMonth() + 1 ;  
this.data = document.getElementById("cat_a_lot_data");
  var d  = "00" + today.getUTCDate() ;
this.mode = document.getElementById("cat_a_lot_mode").checked;
  mo = "00" + mo ;
if (this.mode == false) {
this.data.style.display = "none";


  var h = "00" + today.getUTCHours() ;  
//Unbind click handlers
  var m = "00" + today.getUTCMinutes() ;
this.labels.unbind('click');
  var s = "00" + today.getUTCSeconds() ;
} else {
this.makeClickable();
this.data.style.display = "block";
if (this.searchmode) this.update_cats("Pictures and images");
else this.update_cats(wgTitle);
}
}
};


  var ret = "" ;
if (wgNamespaceNumber == 14) {
  ret +=  y.substr (  y.length - 4 ) ;
$j(document).ready(init_cat_a_lot);
  ret += mo.substr ( mo.length - 2 ) ;
  ret += d.substr (  d.length - 2 ) ;
  ret += h.substr (  h.length - 2 ) ;
  ret +=  m.substr ( m.length - 2 ) ;
  ret +=  s.substr ( s.length - 2 ) ;
  return ret ;
}
}


 
if (wgNamespaceNumber == -1 && wgCanonicalSpecialPageName == "Search") {
 
this.searchmode = true;
function cat_a_lot_move_here ( targetcat ) {
$j(document).ready(init_cat_a_lot);
  cat_a_lot_do_something ( cat_a_lot_decode (targetcat) , 'move' ) ;
}
 
function cat_a_lot_copy_here ( targetcat ) {
  cat_a_lot_do_something ( cat_a_lot_decode (targetcat) , 'copy' ) ;
}
 
function cat_a_lot_remove () {
  cat_a_lot_do_something ( '' , 'remove' ) ;
}
 
function cat_a_lot_do_something ( targetcat , mode ) {
  var files = cat_a_lot_get_marked_labels () ;
  if ( files.length == 0 ) {
    alert ( "No files selected." ) ;
    return ;
  }
  for ( var i = 0 ; i < files.length ; i++ ) {
    cat_a_lot_edit_move ( files[i] , targetcat , mode ) ;
  }
}
 
function cat_a_lot_htmlize (str) {
  return str.replace (/&/g,    '&amp;')
            .replace (/\xa0/g, '&nbsp;')
            .replace (/</g,    '&lt;')
            .replace (/>/g,    '&gt;')
            .replace (/\"/g,  '&quot;') // " // Fix syntax coloring
            .replace (/\'/g,  '&apos;') // ' // Fix syntax coloring
  ;
}
}


function cat_a_lot_encode (str) {
  return encodeURIComponent (str).replace (/'/g, '%27').replace (/"/g, '%22');
}


function cat_a_lot_decode (str) {
  return decodeURIComponent (str.replace (/%27/g, "'").replace (/%22/g, '"'));
}
function cat_a_lot_get_cat_links ( symbol , list ) {
  var ret = "" ;
  list.sort () ;
  for ( var i = 0 ; i < list.length ; i++ ) {
    ret += "<tr style='border:1px solid #AAAAAA'><td>" + symbol + "</td><td>" ;
    ret += '<a href="#" onclick ="cat_a_lot_update_cats(\'' + cat_a_lot_encode (list[i]) + '\', true)">' + cat_a_lot_htmlize (list[i]) + '</a>' ;
    ret += "</td><td>" ;
    if ( list[i] != wgTitle ) { // Can't move to source category
      ret += '<a href="#" onclick ="cat_a_lot_move_here(\'' + cat_a_lot_encode (list[i]) + '\')"><b>Move</b></a> ' ;
      ret += '<a href="#" onclick ="cat_a_lot_copy_here(\'' + cat_a_lot_encode (list[i]) + '\')"><b>Copy</b></a>' ;
    }
    ret += "</td></tr>" ;
  }
  return ret ;
}
function cat_a_lot_show_category_list () {
  var parcats = cat_a_lot_get_parent_categories () ;
  var subcats = cat_a_lot_get_subcategories () ;
  var thiscat = new Array () ;
  thiscat.push ( cat_a_lot_current_category ) ;
 
  var out = "<table border='0'>" ;
  out += cat_a_lot_get_cat_links ( "&uarr;" , parcats ) ;
  out += cat_a_lot_get_cat_links ( "&rarr;" , thiscat ) ;
  out += cat_a_lot_get_cat_links ( "&darr;" , subcats ) ;
  out += "</table>" ;
  catlist = document.getElementById("cat_a_lot_category_list") ;
  catlist.innerHTML = out ;
  document.body.style.cursor = 'auto' ;
}
function cat_a_lot_update_cats ( newcat, encoded ) {
  document.body.style.cursor = 'wait' ;
  if (encoded) newcat = cat_a_lot_decode (newcat);
  cat_a_lot_current_category = newcat ;
  catlist = document.getElementById("cat_a_lot_category_list") ;
  catlist.innerHTML = '<div style="background-color:red;color:white">Loading...</div>' ;
  window.setTimeout("cat_a_lot_show_category_list()", 0);
}
function cat_a_lot_search_cat() {
  var newcat = document.cat_a_lot_searchcat.cat_a_lot_searchcatname.value ;
  cat_a_lot_update_cats ( newcat ) ;
}
function run_cat_a_lot () {
  cat_a_lot_data = document.getElementById("cat_a_lot_data") ;
  cat_a_lot_mode = document.getElementById("cat_a_lot_mode").checked ;
  if ( cat_a_lot_mode == false ) {
    cat_a_lot_data.style.display = "none" ;
    cat_a_lot_mark_all ( 0 ) ;
  } else {
    cat_a_lot_mark_all ( 1 ) ;
    cat_a_lot_data.style.display = "block" ;
    if ( cat_a_lot_searchmode ) cat_a_lot_update_cats ( "Pictures and images" ) ;
    else cat_a_lot_update_cats ( wgTitle ) ;
  }
}
// </source>
// </source>

גרסה מ־15:03, 6 בנובמבר 2010

// <source lang="javascript">
// Variables
String.prototype.trim = function () {
	return this.replace(/^\s+|\s+$/g, "");
};

String.prototype.ucFirst = function () {
	return this.substr(0, 1).toUpperCase() + this.substr(1, this.length);
};

String.prototype.lcFirst = function () {
	return this.substr(0, 1).toLowerCase() + this.substr(1, this.length);
};

String.prototype.replaceAll = function (s, r) {
	return this.split(s).join(r);
};

var catALot = {
	apiUrl: wgScriptPath + "/api.php",
	searchmode: false,


	init_cat_a_lot: function () {
		this.parent = document.getElementById("mw-category-media") || getElementsByClassName(document, "ul", "mw-search-results")[0];
		if (!this.parent) return;

		var c1_div = document.getElementById("column-one");
		if (!c1_div) c1_div = document.getElementById("mw-panel");
		if (!c1_div) return;
		c1_div.innerHTML += '<div id="cat_a_lot">' + '<div id="cat_a_lot_data">' +

		'<div>' + '<form name="cat_a_lot_searchcat" method="post" onSubmit="return false;">' + '<input type="text" input="8" name="cat_a_lot_searchcatname" />' + '<input type="submit" name="cat_a_lot_go" value="Go" onclick="cat_a_lot_search_cat();"/>' + '</form>' + '</div><div id="cat_a_lot_category_list"></div>' + '<div id="cat_a_lot_mark_counter"> </div>' + '<div id="cat_a_lot_selections" >Select <a href="#" id="cat_a_lot_select_all">all</a> / ' + '<a href="#" id="cat_a_lot_select_none">none</a>' + '</div>' + '<div>' + '<a href="#" onclick ="cat_a_lot_remove()"><b>Remove from this category</b></a>' + '</div>' + '<form name="cat_a_lot_edit" enctype="multipart/form-data" method="post" target="_blank">' + '<input type="hidden" name="wpTextbox1" />' + '<input type="hidden" name="wpSummary" />' + '<input type="hidden" name="wpDiff" value="wpDiff" />' + '<input type="hidden" name="wpStarttime" />' + '<input type="hidden" name="wpEdittime" />' + '</form>' + '</div>' + '<div id="cat_a_lot_head" class="pBody">' + '<form><input id="cat_a_lot_mode" type="checkbox" onchange="run_cat_a_lot();"/><label for="cat_a_lot_mode">Cat-a-lot mode</label></form>' + '</div></div>';

		$('#cat_a_lot_select_all').click(function () {
			catALot.toggleAll(true);
		});
		$('#cat_a_lot_select_none').click(function () {
			catALot.toggleAll(false);
		});


		if (skin == "vector") appendCSS("#cat_a_lot {font-size: .75em};");
	},
	findAllLabels: function () {
		if (this.searchmode) this.labels = $('table.searchResultImage td:eq(1)');
		else this.labels = $('div.gallerytext');
	},

	getMarkedLabels: function () {
		var marked = [];
		this.selectedLabels = this.labels.filter('.cat_a_lot_selected');
		this.selectedLabels.each(function () {
			var file = $(this).find('a[title]');
			marked.push(file.attr('title'));
		});
		return marked;
	},

	updateSelectionCounter: function () {
		this.selectedLabels = this.labels.filter('.cat_a_lot_selected');
		$('#cat_a_lot_mark_counter').html(this.selectedLabels.length + " files selected.");
	},

	makeClickable: function () {
		this.findAllLabels();
		this.labels.click(function () {
			$(this).toggleClass('cat_a_lot_selected');
			this.updateSelectionCounter();
		});
	},
	toggleAll: function (select) {

		this.labels.toggleClass('cat_a_lot_selected', select);
		this.updateSelectionCounter();
	},

	get_subcategories: function () {
		var data = {
			action:'query',
			list:'categorymembers',
			cmnamespace:14,
			cmlimit:50
			cmtitle:'Category:'+this.current_category
		};
		
		this.doAPICall(data, function(result) {
			
			//Process the return
			// var cls = xml.getElementsByTagName('cm');
			// var ret = new Array();
			// for (var i = 0; i < cls.length; i++) {
			// 	if (cls[i].getAttribute('ns') != 14) continue; // XXX: partial workaround for MW API bug (cmnamespace parameter doesn't work)
			// 	var title = cls[i].getAttribute('title');
			// 	title = title.split(":", 2)[1];
			// 	ret.push(title);
			// }
			// return ret;

		});
	},
	

	get_parent_categories: function () {
		var data = {
			action:'query',
			prop:'categories',
			titles:'Category:'+this.current_category
		};
		this.doAPICall(data, function(result) {
			
			var cls = xml.getElementsByTagName('cl');
			var ret = new Array();
			for (var i = 0; i < cls.length; i++) {
				var title = cls[i].attributes.getNamedItem("title").value;
				title = title.split(":", 2)[1];
				ret.push(title);
			}
			return ret;

		});
	},

	replaceCategory: function (text, sourcecat, targetcat) {
		var re = new RegExp('\[\[Category:\s*' + catname + '\s*([\||\]\]])','ig');
		return text.replace(re, '[[Category:'+targetcat+'$1');
	},

	removeCategory: function (text, sourcecat) {
		var re = new RegExp('\[\[Category:\s*' + catname + '\s*\]\]','ig');
		return text.replace(re, '');
	},

	edit_move: function (filename, targetcat, mode) {
		var sourcecat = wgTitle;
		var url = this.edit_url + encodeURIComponent(filename) + "&action=raw" + this.dummy_time();
		var xmlreq = sajax_init_object();
		xmlreq.open("GET", url, false);
		xmlreq.send(null);
		var otext = xmlreq.responseText.trim();

		// Check if that file is already in that category
		if (mode != "remove") {
			if (otext.indexOf("ategory:" + targetcat.ucFirst()) != -1 || otext.indexOf("ategory:" + targetcat.lcFirst()) != -1) {
				alert(filename + " is already in category " + targetcat + " - skipping.");
				return;
			}
		}

		// Fix text
		var text = otext;
		if (mode == 'copy') {
			text += "\n[[" + "Category:" + targetcat + "]]\n";
		} else if (mode == 'move') {
			text = this.replaceCategory(text, sourcecat, targetcat);
		} else if (mode == 'remove') {
			text = this.removeCategory();
		}

		if (text == otext) {
			alert("Could not find an occurrence of category " + sourcecat + " in description of file " + filename + " - skipping.");
			return;
		}

		var time = new Date();

		var comment;
		if (mode == "move") comment = "Moving from [[" + "Category:" + sourcecat + "]] to [[" + "Category:" + targetcat + "]]";
		if (mode == "copy") comment = "Copying from [[" + "Category:" + sourcecat + "]] to [[" + "Category:" + targetcat + "]]";
		if (mode == "remove") comment = "Removing from [[" + "Category:" + sourcecat + "]]";
		url = this.edit_url + encodeURIComponent(filename) + "&action=edit";
		// document.this.edit.action = url;
		// document.this.edit.wpSummary.value = comment;
		// document.this.edit.wpTextbox1.value = text;
		// document.this.edit.wpStarttime.value = starttime;
		// document.this.edit.wpEdittime.value = last_version_timestamp;
		// document.this.edit.submit();
		this.alter_label(filename, mode);
	},
	
	alter_label: function (title, mode) {
		var divs = getElementsByClassName(this.parent, this.divtype, this.classname);
		for (var i = 0; i < divs.length; i++) {
			var files = divs[i].getElementsByTagName("a");
			if (files.length == 0) continue;
			if (this.gettitle(files) != title) continue;

			if (mode == "move") {
				divs[i].innerHTML += "<div style=\"width:100%;color:white;background-color:red;text-align:center;\">Moved to new category</div>";
				divs[i].style.backgroundColor = "#FF0000";
			} else if (mode == "remove") {
				divs[i].innerHTML += "<div style=\"width:100%;color:white;background-color:red;text-align:center;\">Removed from category</div>";
				divs[i].style.backgroundColor = "#FF0000";
			} else if (mode == "copy") {
				divs[i].innerHTML += "<div style=\"width:100%;font-weight:bold;\">Copied to new category!</div>";
			}

			return;
		}
	},
	move_here: function (targetcat) {
		this.do_something(this.decode(targetcat), 'move');
	},

	copy_here: function (targetcat) {
		this.do_something(this.decode(targetcat), 'copy');
	},

	remove: function () {
		this.do_something('', 'remove');
	},

	do_something: function (targetcat, mode) {
		var files = this.getMarkedLabels();
		if (files.length == 0) {
			alert("No files selected.");
			return;
		}
		for (var i = 0; i < files.length; i++) {
			this.edit_move(files[i], targetcat, mode);
		}
	},

	htmlize: function (str) {
		return str.replace(/&/g, '&amp;').replace(/\xa0/g, '&nbsp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\"/g, '&quot;') // " // Fix syntax coloring
		.replace(/\'/g, '&apos;') // ' // Fix syntax coloring
		;
	},

	encode: function (str) {
		return encodeURIComponent(str).replace(/'/g, '%27').replace(/"/g, '%22');
	},

	decode: function (str) {
		return decodeURIComponent(str.replace(/%27/g, "'").replace(/%22/g, '"'));
	},

	get_cat_links: function (symbol, list) {
		var ret = "";
		list.sort();
		for (var i = 0; i < list.length; i++) {
			ret += "<tr style='border:1px solid #AAAAAA'><td>" + symbol + "</td><td>";
			ret += '<a href="#" onclick ="this.update_cats(\'' + this.encode(list[i]) + '\', true)">' + this.htmlize(list[i]) + '</a>';
			ret += "</td><td>";
			if (list[i] != wgTitle) { // Can't move to source category
				ret += '<a href="#" onclick ="this.move_here(\'' + this.encode(list[i]) + '\')"><b>Move</b></a> ';
				ret += '<a href="#" onclick ="this.copy_here(\'' + this.encode(list[i]) + '\')"><b>Copy</b></a>';
			}
			ret += "</td></tr>";
		}
		return ret;
	},

	show_category_list: function () {
		var parcats = this.get_parent_categories();
		var subcats = this.get_subcategories();
		var thiscat = new Array();
		thiscat.push(this.current_category);

		var out = "<table border='0'>";
		out += this.get_cat_links("&uarr;", parcats);
		out += this.get_cat_links("&rarr;", thiscat);
		out += this.get_cat_links("&darr;", subcats);
		out += "</table>";

		catlist = document.getElementById("this.category_list");
		catlist.innerHTML = out;
		document.body.style.cursor = 'auto';
	},

	update_cats: function (newcat, encoded) {
		document.body.style.cursor = 'wait';
		if (encoded) newcat = this.decode(newcat);
		this.current_category = newcat;
		catlist = document.getElementById("this.category_list");
		catlist.innerHTML = '<div style="background-color:red;color:white">Loading...</div>';
		window.setTimeout("cat_a_lot_show_category_list()", 0);
	},

	search_cat: function () {
		//var newcat = document.this.searchcat.this.searchcatname.value;
		this.update_cats(newcat);
	},

	run_cat_a_lot: function () {
		this.data = document.getElementById("cat_a_lot_data");
		this.mode = document.getElementById("cat_a_lot_mode").checked;
		if (this.mode == false) {
			this.data.style.display = "none";

			//Unbind click handlers
			this.labels.unbind('click');
		} else {
			this.makeClickable();
			this.data.style.display = "block";
			if (this.searchmode) this.update_cats("Pictures and images");
			else this.update_cats(wgTitle);
		}
	}
};

if (wgNamespaceNumber == 14) {
	$j(document).ready(init_cat_a_lot);
}

if (wgNamespaceNumber == -1 && wgCanonicalSpecialPageName == "Search") {
	this.searchmode = true;
	$j(document).ready(init_cat_a_lot);
}


// </source>