MediaWiki:Gadget-Stockphoto.js

From Open Educational Resources
Jump to navigation Jump to 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 / Edge: 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 2017-10-05
 * @author [[User:Magnus Manske]], 2010 - 2011
 * @author [[User:Krinkle]], 2011 - 2014
 * @source https://commons.wikimedia.org/wiki/MediaWiki:Gadget-Stockphoto.js
 * @license Multi-licensed under CC-BY 3.0, GFDL, MIT
 */
/*jshint quotmark:single, laxbreak:true, browser:true */
/*global jQuery:false, mediaWiki:false */
( function ( $, mw ) {
'use strict';

var stockPhoto,
  clientProfile = $.client.profile();

// 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
  && (('msie' !== clientProfile.name) || (('msie' === clientProfile.name) && clientProfile.versionNumber > 7))
  && (('opera' !== clientProfile.name) || (('opera' === clientProfile.name) && parseFloat(clientProfile.version) > 9.27))
) {

  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', '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" href="#enableStockphoto">' + stockPhoto.i18n.reuse + '</a></li>');
        $enable.click(function (e){
          e.preventDefault();
          $.cookie('StockPhotoDisabled', null, {
            path: '/'
          });
          stockPhoto.init();
        });
        $('#filetoc').append($enable);
        return;
      }
      if ( $('#file').length === 0 ) {
        return;
      }
      stockPhoto.small_horizontal_layout = false;
      if ( !mw.user.isAnon() ) {
        stockPhoto.small_horizontal_layout = true;
      }
      has_information = false;
      $.each( stockPhoto.information_template_hints, function (k, v) {
        if ( $('#' + v).length ) {
          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 = $('.multipageimage, #file img').eq(0).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="right: ' + xoff + 'px; 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').on('mouseenter', function () {
        $(this).find('span:first a').fadeTo('fast', 1);
      }).on('mouseleave', function () {
        $(this).find('span:first a').fadeTo('fast', 0.7);
      });
      $('#stockphoto_remove').on('mouseenter', function () {
        $(this).fadeTo('fast', 1);
      }).on('mouseleave', function () {
        $(this).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 (i, v) {
      	v = $(v);
      	i = v.attr('alt');
        if ( i && i !== alt_title )
          return;
        thumb_url = v.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('/');
      return thumb_url;
    },

    is_audio_video_asset: function(url){
      var ext = url.substr(-3);
      if( ext === 'ogv' || ext === 'ogg' || ext === 'oga' || ext === 'ebm'){
        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 +
          '?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_element, source_element, author, source;

      author_element = $('#fileinfotpl_aut + td');
      source_element = $('#fileinfotpl_src + td');
      author = $.trim(author_element.text());
      source = $.trim(source_element.text());

      // Remove boiler template
      if (author_element.find('.boilerplate').length) {
        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
      if (source_element.find('.boilerplate').length) {
        source = '';
      }
      // Remove "own work" notice
      if (author !== '' && $('#own-work').length) {
        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) {
          licenses.push(cL);
        }
      });

      if (licenses.length) {
        $.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,
        pixelStr, widthSearchMatch, imageWidth, power, i;

      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');
      }

      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 + '//teacher-network.in/OER/' + 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 {
        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) + '" download>' + v + 'px</a>');
          });
          if (stockPhoto.file_url) {
            dl_links.push('<a href="' + stockPhoto.file_url + '" download>' + 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.getUrl( 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/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
    }).done( stockPhoto.init );

  } else {
    $( stockPhoto.init );
  }
}

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

}( jQuery, mediaWiki) );