לדלג לתוכן

מדיה ויקי:Gadget-Cat-a-lot.js

מתוך צפונות ויקי

הערה: לאחר הפרסום, ייתכן שיהיה צורך לנקות את זיכרון המטמון (cache) של הדפדפן כדי להבחין בשינויים.

  • פיירפוקס / ספארי: להחזיק את המקש Shift בעת לחיצה על טעינה מחדש (Reload) או ללחוץ על צירוף המקשים Ctrl-F5 או Ctrl-R (במחשב מק: ⌘-R).
  • גוגל כרום: ללחוץ על צירוף המקשים Ctrl-Shift-R (במחשב מק: ⌘-Shift-R).
  • אדג': להחזיק את המקש Ctrl בעת לחיצה על רענן (Refresh) או ללחוץ על צירוף המקשים Ctrl-F5.
// <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>