MediaWiki:Gadget-Stockphoto.js

From The BenHaven Archives
Jump to: navigation, search

Note: After saving, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
/*
 * StockPhoto - shows download and attribution buttons
 * Original code 2010-09/10 by [[User:Magnus Manske]]
 *
 * @rev 33 (2012-01-02)
 * @author [[User:Magnus Manske]], 2010 - 2011
 * @author [[User:Krinkle]], 2011 - 2012
 * @source commons.wikimedia.org/archives/legacy/wiki/MediaWiki:Gadget-Stockphoto.js
 */
/*jslint browser: true, white: true */
/*global jQuery:false, mediaWiki:false, importScript:false*/
( function ( $, mw, undefined ) {
"use strict";

// Disabled for Internet Explorer, Opera 9.27 and below
if (
	window.stockPhoto === undefined
	&& ( mw.config.get( 'skin' ) === 'vector' || mw.config.get( 'skin' ) === 'monobook' )
	&& mw.config.get( 'wgNamespaceNumber' ) === 6
	&& $.inArray( mw.config.get( 'wgAction' ), ['view', 'purge'] ) !== -1
	&& !$.browser.msie
	&& (!$.browser.opera || ($.browser.opera && parseFloat($.browser.version) > 9.27))
) {

	var stockPhoto = {

		// Misc
		ui_icon_download: '//upload.wikimedia.org/wikipedia/commons/thumb/9/92/Gnome-document-save.svg/50px-Gnome-document-save.svg.png',
		ui_icon_web: '//upload.wikimedia.org/wikipedia/commons/thumb/c/c0/Gnome-emblem-web.svg/50px-Gnome-emblem-web.svg.png',
		ui_icon_wiki: '//upload.wikimedia.org/wikipedia/commons/thumb/2/2c/Tango_style_Wikipedia_Icon.svg/50px-Tango_style_Wikipedia_Icon.svg.png',
		ui_icon_email: '//upload.wikimedia.org/wikipedia/commons/thumb/e/ee/Gnome-mail-send.svg/50px-Gnome-mail-send.svg.png',
		ui_icon_help: '//upload.wikimedia.org/wikipedia/commons/thumb/e/e7/Dialog-information_on.svg/50px-Dialog-information_on.svg.png',
		ui_icon_remove: '//upload.wikimedia.org/wikipedia/commons/thumb/9/9d/Emblem-unreadable.svg/20px-Emblem-unreadable.svg.png',
		information_template_hints: ['fileinfotpl_desc', 'fileinfotpl_src'],
		icons_only: ['midi', 'ogg', 'flac'],
		horizontal_ui: ['midi', 'ogg', 'flac', 'pdf', 'djvu'],
		//license_patterns: "^Artistic-2$", "^BSD images$", "^OS OpenData$", "^Mozilla Public License$"],
		ogg_icon: mw.config.get( 'stylepath' ) + '/common/images/icons/fileicon-ogg.png',
		stockphoto_code1: undefined,
		stockphoto_author: undefined,
		stockphoto_license: undefined,
		nicetitle: undefined,
		file_icon: undefined,
		file_url: undefined,
		backlink_url: undefined,
		attribution: '',
		fade_target: '',
		gfdl_note: false,
		sbm_counter: 1,
		fromCommons: false,
		attrRequired: true,

		init: function () {
			var $enable, has_information, img_width, img_height, xoff, yoff, horizontal, html;

			if ( window.stockphoto_prevent !== undefined ) {
				return;
			}
			$("#filetoc").find("a[href=#file], a[href=#filehistory], a[href=#filelinks], a[href=#metadata], a[href=#globalusage]").parent().addClass("mw-filetoc-links");
			if ($.cookie('StockPhotoDisabled')) {
				$enable = $('<li class="mw-filetoc-links"><a id="SpEnable">' + stockPhoto.i18n.reuse + '</a></li>');
				$enable.click(function (){
					$.cookie('StockPhotoDisabled', null, {
						path: '/'
					});
					stockPhoto.init();
				});
				$("#filetoc").append($enable);
				return;
			}
			if ( $('#file').length === 0 ) {
				return;
			}
			stockPhoto.small_horizontal_layout = false;
			if ( !mw.user.anonymous() ) {
				stockPhoto.small_horizontal_layout = true;
			}
			has_information = false;
			$.each( stockPhoto.information_template_hints, function (k, v) {
				if ($('#' + v).length !== 0) {
					has_information = true;
				}
			});

			// No {{Information}}
			if (!has_information) {
				return;
			}

			// Has one or more problemtags
			// Changed to also include renames and normal deletes
			if ($('.nuke').length) {
				return;
			}

			$('#stockphoto_base').remove();
			img_width = $('#file img').width();
			img_height = $('#file img').height();
			xoff = img_width + 40;
			yoff = $('#file').position().top + 5;

			if (!horizontal && img_height < 300) {
				stockPhoto.small_horizontal_layout = true;
			}
			horizontal = stockPhoto.small_horizontal_layout;
			$.each(stockPhoto.horizontal_ui, function (k, v) {
				v = new RegExp('\.' + v + '$', 'i');
				if ( mw.config.get( 'wgTitle' ).match(v)) {
					horizontal = true;
				}
			});
			if ($(window).width() < 1030) {
				horizontal = true;
			}

			// Initialize values
			stockPhoto.share_this(-1);
			html = '<div id="stockphoto_base" ';
			if (horizontal) {
				html += ' class="horizontal">';
			}
			else if (!$("body.rtl").length) {
				html += "class='vertical' style='left:" + xoff + "px;top:" + yoff + "px'>";
			} else {
				html += "class='vertical' style='left: 0px;top:" + yoff + "px'>";
			}

			html += stockPhoto.add_button_row( stockPhoto.ui_icon_download, "call_download", stockPhoto.i18n.download, stockPhoto.i18n.all_sizes, horizontal);
			html += stockPhoto.add_button_row( stockPhoto.ui_icon_web, "call_web", stockPhoto.i18n.use_this_file_web_short, stockPhoto.i18n.on_a_website, horizontal);
			html += stockPhoto.add_button_row( stockPhoto.ui_icon_wiki, "call_wiki", stockPhoto.i18n.use_this_file_wiki_short, stockPhoto.i18n.on_a_wiki, horizontal);
			html += stockPhoto.add_button_row( stockPhoto.ui_icon_email, "send_email", stockPhoto.i18n.email_link_short, stockPhoto.i18n.to_this_file, horizontal);
			html += stockPhoto.add_button_row( stockPhoto.ui_icon_help, "call_help", stockPhoto.i18n.information, stockPhoto.i18n.about_reusing, horizontal);
			html += '<a title="' + stockPhoto.i18n.remove_icons + '" id="stockphoto_remove"><img src="' + stockPhoto.ui_icon_remove + '" /></a>';
			html += "</div>";
			if ( stockPhoto.small_horizontal_layout && $("#file").length ) {
				$(".mw-filetoc-links").hide();
				$("#filetoc").append(html);
			} else {
				$("#filetoc").after(html);
			}
			$('#stockphoto_remove').click(function () {
				$.cookie('StockPhotoDisabled', true, {
					expires: 60,
					path: '/'
				});
				$('#stockphoto_base').remove();
				$(".mw-filetoc-links").show();
			});

			$('#stockphoto_base img').parent().fadeTo(0, 0.7);
			$('#stockphoto_base>span').hover(function () {
				$(this).find('span:first a').fadeTo('fast', 1);
			}, function () {
				$(this).find('span:first a').fadeTo('fast', 0.7);
			});

		},

		/**
		 * @todo Parameter "horizontal" is unused
		 */
		add_button_row: function (icon_url, fkt, txt, html, horizontal) {
			var imgid, a, ret;

			if ( stockPhoto.small_horizontal_layout) {
				icon_url = icon_url.replace('/50px-', '/20px-');
			}
			imgid = 'stockphoto_icon_' + fkt;
			a = '<a href="#" title="' + txt + ' ' + html + '" onclick="stockPhoto.' + fkt + '(); return false;">';

			ret = "<span id='stockphoto_" + fkt + "'>";
			ret += "<span class='stockphoto_buttonrow_icon'>" + a + "<img id='" + imgid + "' src='" + icon_url + "' /></a></span>";
			ret += "<span class='stockphoto_buttonrow_text'>" + a;
			if ( stockPhoto.small_horizontal_layout) {
				ret += txt + "</a>";
			} else {
				ret += "<b>" + txt + "</b></a><br/>" + html;
			}
			ret += "</span></span>";
			return ret;
		},

		stockphoto_get_thumbnail_url: function (width) {
			var thumb_url, alt_title, last;

			if ( stockPhoto.file_icon !== undefined ) {
				return stockPhoto.file_icon;
			}
			alt_title = mw.config.get( 'wgCanonicalNamespace' ) + ':' + mw.config.get( 'wgTitle' );
			$('#file img').each(function () {
				if ($(this).attr('alt') !== alt_title) {
					return;
				}
				thumb_url = $(this).attr('src').split('/');
			});
			// Special case of mwEmbed rewrite
			if( !thumb_url && $('#mwe_ogg_player_1').length ){
				return $('#mwe_ogg_player_1').find('img').attr('src');
			}
			if( !thumb_url || thumb_url.length < 1 ) {
				return;
			}

			last = thumb_url.pop().replace(/^\d+px-/, width + 'px-');
			thumb_url.push(last);
			thumb_url = thumb_url.join('/');
			thumb_url = location.protocol + thumb_url;
			return thumb_url;
		},

		is_audio_video_asset: function(url){
			var ext = url.substr(-3);
			if( ext === 'ogv' || ext === 'ogg' || ext === 'oga' ){
				return true;
			}
			return false;
		},

		/**
		 * @param e {jQuery.Event} [optional]
		 */
		make_html_textarea: function (e) {
			var width, type, height, thumb_url, t;

			if(e) {
				e.preventDefault();
			}

			width = $('#stockphoto_html_select').val();
			type = $('input[name="stockphoto_code_type"]:checked').val();

			// Iframe share for mwEmbed player
			if( stockPhoto.is_audio_video_asset( stockPhoto.backlink_url ) && type === 'html' ){
				// Get the ratio ( from html or from mwEmbed player ) 
				height = $('#mwe_ogg_player_1').width() 
					? width * $('#mwe_ogg_player_1').height() / $('#mwe_ogg_player_1').width()
					: width * $('#file img,#file video').height() / $('#file img,#file video').width();

				// For audio that has zero height: 
				if ( height === 0 ) {
					height = 20;
				}
				$('#stockphoto_html').text( '<iframe src="' + stockPhoto.backlink_url + 
					'?withJS=MediaWiki:MwEmbed.js&embedplayer=yes" width="' + width + '" height="'+ height + '" frameborder="0" ></iframe>' );
				return;
			}

			thumb_url = stockPhoto.stockphoto_get_thumbnail_url(width);

			if (type === 'html') {
				t = '<a title="' + stockPhoto.escapeAttribute( stockPhoto.complete_attribution_text) + '" href="' + stockPhoto.backlink_url + '"><img width="' + width + '" alt="' + stockPhoto.escapeAttribute( stockPhoto.nicetitle) + '" src="' + thumb_url + '"/></a>';
			} else if (type === 'bbcode') {
				t = "[url=" + stockPhoto.backlink_url + "][img]" + thumb_url + "[/img][/url]\n[url=" + stockPhoto.backlink_url + "]" + stockPhoto.nicetitle + "[/url]" + stockPhoto.stockphoto_license + ", " + stockPhoto.i18n.by + ' ' + stockPhoto.stockphoto_author + ", " + stockPhoto.i18n.from_wikimedia_commons;
			}
			$('#stockphoto_html').text(t);
		},

		get_author_attribution: function (use_html) {
			var author, source;

			author = $.trim($("#fileinfotpl_aut + td").text());
			source = $.trim($("#fileinfotpl_src + td").text());

			// Remove boiler template; not elegant, but...
			if (author.match(/This file is lacking author information/)) {
				author = '';
			}
			if (author.match(/^[Uu]nknown$/)) {
				author = '';
			}
			author = author.replace(/\s*\(talk\)$/i, '');

			if (author.indexOf('Original uploader was') !== -1) {
				author = author.replace(/\s*Original uploader was\s*/g, '');
				stockPhoto.fromCommons = true;
			}
			// Remove boiler template; not elegant, but...
			if (source.match(/This file is lacking source information/)) {
				source = '';
			}
			if (author !== '' && $('#own-work').length) { // Remove "own work" notice
				source = '';
				stockPhoto.fromCommons = true;
			}
			if (author !== '' && source.length > 50) {
				source = ''; // Remove long source info
			}
			if (author.substr(0, 3) === '[&#9660;]') {
				author = author.substr(3);
				author = $.trim(author.split('Description').shift());
			}

			stockPhoto.attribution = '';
			if (author !== '') {
				stockPhoto.attribution = author;
			}
			if (source !== '') {
				if ( stockPhoto.attribution !== '') {
					stockPhoto.attribution += ' (' + source + ')';
				} else {
					stockPhoto.attribution = source;
				}
			}
			stockPhoto.stockphoto_author = stockPhoto.attribution;
			if (author !== '') {
				stockPhoto.attribution = stockPhoto.i18n.by_u + ' ' + stockPhoto.attribution;
			} else {
				stockPhoto.attribution = stockPhoto.i18n.see_page_for_author;
			}

			if ($('#creator').length) {
				stockPhoto.attribution = $('#creator').text();
			}

			if ($('.licensetpl_aut').length) {
				if (use_html) {
					stockPhoto.attribution = $('.licensetpl_aut').eq(0).html();
				}
				else {
					stockPhoto.attribution = $('.licensetpl_aut').eq(0).text();
				}
			}

			if ($('.licensetpl_attr').length) {
				if (use_html) {
					stockPhoto.attribution = $('.licensetpl_attr').eq(0).html();
				} else {
					stockPhoto.attribution = $('.licensetpl_attr').eq(0).text();
				}
			}

			if ($("#fileinfotpl_credit + td").length) {
				if (use_html) {
					stockPhoto.attribution = $("#fileinfotpl_credit + td").html();
				} else {
					stockPhoto.attribution = $("#fileinfotpl_credit + td").text();
				}
			}

		},

		get_license: function (generate_html) {
			var licenses, $readable, l2, l1;

			licenses = [];
			$readable = $('.licensetpl');

			if (!$readable.length) {
				stockPhoto.stockphoto_license = "[" + stockPhoto.i18n.see_page_for_license + "]";
				return;
			}
			$readable.each(function () {
				var cL = {
					link: $(this).find('.licensetpl_link').html(),
					short: $(this).find('.licensetpl_short').html(),
					long: $(this).find('.licensetpl_long').html(),
					attr: $(this).find('.licensetpl_attr').html(),
					aut: $(this).find('.licensetpl_aut').html(),
					link_req: $(this).find('.licensetpl_link_req').html(),
					attr_req: $(this).find('.licensetpl_attr_req').html()
				};

				if (cL.short !== null) {
					licenses.push(cL);
				}
			});

			if (licenses.length > 0) {
				$.each(licenses, function (k, v) {
					if (v.attr_req === 'false') {
						stockPhoto.attrRequired = false;
					}
					if (v.short.indexOf('GFDL') !== -1) {
						stockPhoto.gfdl_note = true;
					}
					if (generate_html && v.link) {
						licenses[k] = '<a href="' + v.link + '">' + v.short + '</a>';
					} else {
						if (v.link_req === 'true') {
							licenses[k] = v.short + ' (' + v.link + ')';
						} else {
							licenses[k] = v.short;
						}
					}
				});

				if (licenses.length > 1) {
					l2 = licenses.pop();
					l1 = licenses.pop();
					licenses.push(l1 + ' ' + stockPhoto.i18n.or + ' ' + l2);
				}
				stockPhoto.stockphoto_license = ' [' + licenses.join(', ') + ']';
			} else {
				stockPhoto.stockphoto_license = ' [' + stockPhoto.i18n.see_page_for_license + ']';
			}
		},

		get_attribution_text: function () {
			var from, html, text;

			from = stockPhoto.fromCommons ? stockPhoto.i18n.from_wikimedia_commons : stockPhoto.i18n.via_wikimedia_commons;
			html = !!$('#stockphoto_attribution_html:checked').length;

			stockPhoto.get_license(html);
			stockPhoto.get_author_attribution(html);

			if ($('#fileinfotpl_credit + td').length) {
				text = stockPhoto.attribution;
			} else {
				text = stockPhoto.attribution + stockPhoto.stockphoto_license;
			}

			if (html) {
				text += ", <a href='" + stockPhoto.escapeAttribute( stockPhoto.backlink_url ) + "'>" + from + "</a>";
			} else {
				text += ', ' + from;
			}

			return text;
		},

		refresh_attribution: function () {
			$("#stockphoto_attribution").val( stockPhoto.get_attribution_text() );
		},

		createDialogRow: function (label, prefill, id) {
			var idtext = (id) ? 'id="' + id + '"' : '';
			return '<div class="stockphoto_dialog_row"><b>' + label + ':</b><br><input type="text" readonly ' + idtext + ' onClick="select()" value="' + prefill + '"/></div>';
		},

		share_this: function (ui_mode) {
			var widths, html, dtitle, dl_links, best_fit;

			stockPhoto.complete_attribution_text = stockPhoto.get_attribution_text();

			stockPhoto.file_url = $('#file > a').attr('href');
			if ( !stockPhoto.file_url ) {
				stockPhoto.file_url = $('#file > div > div > a').attr('href');
			}
			if ( !stockPhoto.file_url ) {
				stockPhoto.file_url = $('div.fullMedia a').attr('href');
			}
			if ( stockPhoto.file_url ) {
				stockPhoto.file_url = location.protocol + stockPhoto.file_url;
			}

			stockPhoto.nicetitle = mw.config.get( 'wgTitle' ).split('.');
			stockPhoto.nicetitle.pop();
			stockPhoto.nicetitle = stockPhoto.nicetitle.join('.');

			$.each( stockPhoto.icons_only, function (i, v) {
				var re = new RegExp('\.' + v + '$', 'i');
				if (!mw.config.get( 'wgPageName' ).match(re)) {
					return;
				}
				stockPhoto.file_icon = stockPhoto.ogg_icon;
			});

			stockPhoto.backlink_url = location.protocol + '//commons.wikimedia.org/archives/legacy/wiki/' + encodeURIComponent(mw.config.get( 'wgPageName' )); 
			
			// Grab width in pixel from DOM, and trim it down
			// This does not yet work for SVGs or videos
			widths = [];
			try {
				var pixelStr, widthSearchMatch, imageWidth, power, i;

				pixelStr = $('.fileInfo').contents().get(0).data;
				widthSearchMatch = /([0-9 ,.\u00a0]+)\s*×/.exec(pixelStr);
				imageWidth = parseInt(widthSearchMatch[1].replace(/[ ,.\u00a0]/g, ''), 10);
				if (isNaN(imageWidth)) {
					throw new Error( 'Cannot parse' );
				}

				// Calculate to which power of two we should go
				power = Math.floor(Math.log(imageWidth) / Math.log(2));

				// Push 6 width to array
				for ( i = 0; i < 5; i += 1 ) {
					widths.push(Math.pow(2, power-i));
				}
				widths = widths.reverse();
				
			} catch (e) {
				widths = [75, 100, 120, 240, 500, 640, 800, 1024];
			}
			if (ui_mode === -1) {
				return;
			}

			html = '';
			html += stockPhoto.createDialogRow( stockPhoto.i18n.page_url, stockPhoto.escapeAttribute( stockPhoto.backlink_url ) );
			html += stockPhoto.createDialogRow( stockPhoto.i18n.file_url, stockPhoto.escapeAttribute( stockPhoto.file_url ) );
			html += stockPhoto.createDialogRow( stockPhoto.i18n.attribution, stockPhoto.escapeAttribute( stockPhoto.complete_attribution_text ), 'stockphoto_attribution');
			html += "<input id='stockphoto_attribution_html' onclick='stockPhoto.refresh_attribution()' type='checkbox' /><label for='stockphoto_attribution_html'>" + stockPhoto.i18n.html + "</label>";
			if ( stockPhoto.gfdl_note ) {
				html += '<br/><span class="stockphoto_note">' + stockPhoto.i18n.gfdl_warning + '</span>';
			}
			if ( !stockPhoto.attrRequired ) {
				html += '<br/><span class="stockphoto_note">' + stockPhoto.i18n.no_attr + '</span>';
			}

			switch (ui_mode) {
			case 1:

				dtitle = stockPhoto.i18n.download_this_file;
				if ( stockPhoto.file_url !== undefined ) {
					html += '<div><b>' + stockPhoto.i18n.download_image_file + ':</b><br>';
					dl_links = [];
					$.each(widths, function (i, v) {
						if ( stockPhoto.file_icon !== undefined ) {
							return;
						}
						dl_links.push("<a href='" + stockPhoto.stockphoto_get_thumbnail_url(v) + "'>" + v + 'px</a>');
					});
					if (stockPhoto.file_url) {
						dl_links.push("<a href='" + stockPhoto.file_url + "'>" + stockPhoto.i18n.full_resolution + '</a>');
					}
					if (dl_links.length) {
						html += dl_links.join(' | ');
					} else {
						html += '<i>' + stockPhoto.i18n.not_available + '</i>';
					}
					html += '</div>';
				}


				break;

			case 2:
				dtitle = stockPhoto.i18n.use_this_file_web;
				html += "<div class='stockphoto_dialog_row'><div style='float:right'>";
				html += "<input type='radio' name='stockphoto_code_type' value='html' id='stockphoto_code_type_html' onchange='stockPhoto.make_html_textarea();' checked /><label for='stockphoto_code_type_html'>" + stockPhoto.i18n.html + "</label> ";
				html += "<input type='radio' name='stockphoto_code_type' value='bbcode' id='stockphoto_code_type_bbcode' onchange='stockPhoto.make_html_textarea();' /><label for='stockphoto_code_type_bbcode'>" + stockPhoto.i18n.bbcode + "</label> ";

				html += '<select id="stockphoto_html_select" onchange="stockPhoto.make_html_textarea();">';
				best_fit = 75;
				if ( stockPhoto.file_icon !== undefined ) {
					best_fit = 120;
					html += "<option value='120'>120" + stockPhoto.i18n.px_wide_icon + "</option>";
				} else {
					$.each(widths, function (i, v) {
						if (v <= $('#file img').width()) {
							best_fit = v;
						}
						html += "<option value='" + v + "'>" + v + stockPhoto.i18n.px_wide + "</option>";
					});
				}
				html += '</select></div>';
				html += '<b>' + stockPhoto.i18n.html + '/' + stockPhoto.i18n.bbcode + ':</b><textarea onClick="select()" id="stockphoto_html" readonly="readonly" style="font-size:9pt">';
				html += '</textarea></div>';

				break;

			case 3:
				dtitle = stockPhoto.i18n.use_this_file_wiki;

				html = stockPhoto.createDialogRow(stockPhoto.i18n.thumbnail, stockPhoto.escapeAttribute('[[File:' + mw.config.get( 'wgTitle' ) + '|thumb|' + stockPhoto.nicetitle + ']]'));
				html += stockPhoto.createDialogRow(stockPhoto.i18n.image, stockPhoto.escapeAttribute('[[File:' + mw.config.get( 'wgTitle' ) + '|' + stockPhoto.nicetitle + ']]'));

				break;
			}

			$("<div style='display:none' id='stockphoto_dialog'></div>").html(html).dialog({
				modal: true,
				width: 610,
				height: "auto",
				title: dtitle,
				close: function () {
					$(this).remove();
				}
			});
			$('#stockphoto_html_select').val(best_fit);

			stockPhoto.make_html_textarea();
			$('#stockphoto_attribution_html').prev().css('width', '90%');
		},

		call_download: function () {
			stockPhoto.share_this(1);
		},

		call_web: function () {
			stockPhoto.share_this(2);
		},

		call_wiki: function () {
			stockPhoto.share_this(3);
		},

		call_help: function () {
			window.location.href = mw.util.wikiGetlink( stockPhoto.i18n.reusing_content_url );
		},

		send_email: function () {
			var url = 'mailto:?subject=' + encodeURIComponent(stockPhoto.nicetitle) + "&body=" + encodeURIComponent(stockPhoto.backlink_url + "\n\n" + stockPhoto.complete_attribution_text + ' ' + stockPhoto.i18n.from_wikimedia_commons);
			window.location.href = url;
		},

		escapeAttribute: function (s) {
			if ( s === undefined ) {
				return '';
			}
			return s.replace(/\n/g, ' ').replace(/\r/g, ' ').replace(/"/g, '&quot;').replace(/'/g, '&#039;');
		},

		i18n: {
			reuse: 'Reuse this file',
			download: 'Download',
			download_this_file: 'Download this file',
			use_this_file_web: 'Use this file on the web',
			use_this_file_web_short: 'Use this file',
			use_this_file_wiki: 'Use this file on a wiki',
			use_this_file_wiki_short: 'Use this file',
			email_link_short: 'Email a link',
			information: 'Information',
			remove_icons: 'Remove these icons',
			all_sizes: 'all sizes',
			on_a_website: 'on the web',
			on_a_wiki: 'on a wiki',
			to_this_file: 'to this file',
			about_reusing: 'about reusing',
			look_what_i_found: 'Look what I found on Wikimedia Commons : ',
			from_wikimedia_commons: 'from Wikimedia Commons',
			via_wikimedia_commons: 'via Wikimedia Commons',
			by: 'by',
			by_u: 'By',
			see_page_for_author: 'See page for author',
			see_page_for_license: 'see page for license',
			page_url: 'Page URL',
			file_url: 'File URL',
			attribution: 'Attribution',
			no_attr: 'Attribution not legally required',
			or: 'or',
			gfdl_warning: 'Using this file might require attaching a full copy of the <a href="//en.wikipedia.org/archives/legacy/wiki/GNU_Free_Documentation_License">GFDL</a>',
			download_image_file: 'Download image file',
			full_resolution: 'Full resolution',
			not_available: 'not available',
			share_this_file: 'Share this file',
			html: 'HTML',
			bbcode: 'BBCode',
			px_wide_icon: 'px wide (icon)',
			px_wide: 'px wide',
			wikipedia_instant_commons: 'Wikimedia/InstantCommons',
			thumbnail: 'Thumbnail',
			image: 'Image',
			reusing_content_url: 'Commons:Reusing_content_outside_Wikimedia'
		}
	};

	/* Expose globally */
	window.stockPhoto = stockPhoto;

	if (mw.config.get( 'wgUserLanguage' ) !== 'en') {
		$.ajax({
			url: mw.util.wikiScript(),
			dataType: 'script',
			data: {
				title: 'MediaWiki:Gadget-Stockphoto.js/' + mw.config.get( 'wgUserLanguage' ),
				action: 'raw',
				ctype: 'text/javascript',
				// Allow caching for 28 days
				maxage: 2419200,
				smaxage: 2419200
			},
			cache: true,
			success: stockPhoto.init
		});
	} else {
		$(document).ready( stockPhoto.init );
	}
}

// i18n on subpages [[MediaWiki:stockPhoto.js/langcode]]:
// stockPhoto.i18n = { ... }

}( jQuery, mediaWiki) );