Dingusfarm.js

// 
// @#@ INSTRUCTIONS END @#@
/*
1. paste the entire page code in your console on any wiki page (in the cpw)
2. add to the text area on the top of the page (added by the script) the json of the wanted file
2.1. see the json files for catalogs at http://clubpenguin.wikia.com/wiki/Club_Penguin_Wiki:JSON#Mobile_catalogs
3. press the "go" button
4. when loaded, use the buttons to navigate
*/
// @#@ INSTRUCTIONS - START @#@
$("#mw-content-text").prepend('<nav id="cpw-catalog-widget-footest"><textarea></textarea><input type="button" value="go" /></nav>');
mw.util.addCSS(
	'nav.cpw-catalog-widget {\n' +
		'\tmargin: 0;\n' +
		'\tpadding: 0;\n' +
		'\tposition: relative;\n' +
	'}\n' +
	'nav.cpw-catalog-widget svg {\n' +
		'\tposition: absolute;\n' +
		'\ttop: 0;\n' +
		'\tleft: 0;\n' +
		'\tz-index: 2;\n' +
	'}'
);
/*
	<nav class="cpw-catalog-widget">
		<svg>
			The <canvas> element could not be loaded. If the company that has made your browser claims that they are not Microsoft, you have been bankrupt.
		</svg>
		<canvas>
			The <canvas> element could not be loaded. If the company that has made your browser claims that they are not Microsoft, you have been bankrupt.
		</canvas>
	</nav>
*/
$cp.catalog = {
	data: {},
	fn: {}
}
/* ==================== *\
	# data
\* ==================== */
$.extend($cp.catalog.data, {
	pngBaseURL: "http://media8.clubpenguin.com/mobile/cp-mobile-ui/clubpenguin_v1_6/en_US/deploy/metaplace/devicepng/assets/",
	data: {}, // json data
	svgRectFill: "rgba(0, 0, 0, 0.003)"
});
/* ==================== *\
	# functions
\* ==================== */
$.extend($cp.catalog.fn, {
	/*
		NOTE!
		the passed 'node' variable is used as the grouping <nav> element for the canvas and the svg
	*/
	// update dimensions of canvas
	updateNavDimensions: function(nav, data) {
		var w = data.sourceWidth,
			h = data.sourceHeight,
			zoom = $(nav).width() / w;
		zoom = zoom < 1 ? zoom : 1; // don't scale up if source is smaller than canvas container
		$(nav).css({
			zoom: zoom,
			width: w,
			border: "1px solid #333;"
		}).find("canvas, svg").attr({
			width: w,
			height: h
		});
	},
	// clear canvas and svg of a given nav
	clear: function(nav) {
		nav.querySelector("canvas").getContext("2d").clearRect(0, 0, 10000, 10000);
		var svg = nav.querySelector("svg");
		while (svg.childNodes.length > 0) {
			svg.removeChild(svg.childNodes[0]);
		}
	},
	// construct page
	drawPage: function(nav, page) {
		var a = $cp.catalog.data.data.components[page];
		if (a) {
			$(nav).attr("data-page", page);
			var b = a.layout,
				canvas = nav.querySelector("canvas"),
				svg = nav.querySelector("svg");
			// this.clear(nav); // <-- do not clear: in case 2 pages needed to be loeaded together in 2 function calls
			for (var i in b.images) {
				var c = b.images[i];
				this.drawImage(nav, c.width, c.height, c.originX, c.originY, $cp.catalog.data.pngBaseURL + c.image);
			}
			for (var i in b.frames) {
				var c = b.frames[i];
				this.drawSVGLabel(nav, c.width, c.height, c.originX + a.originX, c.originY + a.originY, c.name, c.configurator_id);
			}
		} else {
			console.log("Page #" + page + " does not exist!");
		}
	},
	// draw image
	drawImage: function(nav, w, h, x, y, url) {
		console.log("Image drawn: " + url);
		var canvas = nav.querySelector("canvas"),
			svg = nav.querySelector(svg),
			ctx = canvas.getContext("2d"),
			img = new Image();
		img.onload = function() {
			ctx.drawImage(img, x, y, w, h);
		}
		img.src = url;
	},
	// draw svg label
	drawSVGLabel: function(nav, w, h, x, y, name, id) {
		var rect = document.createElementNS("http://www.w3.org/2000/svg", "rect"),
			title = document.createElementNS("http://www.w3.org/2000/svg", "title");
		rect.setAttributeNS(null, "width", w);
		rect.setAttributeNS(null, "height", h);
		rect.setAttributeNS(null, "x", x);
		rect.setAttributeNS(null, "y", y);
		rect.setAttributeNS(null, "fill", $cp.catalog.data.svgRectFill); // can't use "none" or "transparent" since the title is not displayed
		title.textContent = "Name: " + name + "\nID: " + id;
		rect.appendChild(title);
		nav.querySelector("svg").appendChild(rect);
	},
	// apply on a given nav
	apply: function(nav) {
		this.updateNavDimensions(nav, $cp.catalog.data.data);
		this.drawPage(nav, 0);
	}
});
// @@@@@@@@@@@@@@@@@@@@@@@
// # D E B U G G I N G
// @@@@@@@@@@@@@@@@@@@@@@@
$("#cpw-catalog-widget-footest input").click(function() {
	try {
		$cp.catalog.data.data = JSON.parse($(this).prev().val());
	} catch(err) {}
	$(this).parent().replaceWith('<nav class="cpw-catalog-widget" data-catalog="" data-page="0"><svg></svg><canvas></canvas><input type="button" value="Prev page" data-role="prev" /> <input type="button" value="Next page" data-role="next" /></nav>');
	$("nav.cpw-catalog-widget").each(function() {
		$cp.catalog.fn.apply(this);
		$(this).find("[data-role]").click(function() {
			var nav = this.parentNode.parentNode;
			$cp.catalog.fn.clear(nav);
			$cp.catalog.fn.drawPage(
				nav,
				Number($(nav).attr("data-page")) +
				(
					1 *
					($(this).attr("data-role") == "prev" ? -1 : 1) // -1 if prev, +1 if next
				)
			);
		});
	});
});
//