MediaWiki:Gadget-PrettyLog.js

From Wikipedia

Note: After publishing, 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: Press Ctrl-F5.
// <source lang="javascript">
 
/*
   PrettyLog - reformat log pages. If the log contains file uploads, add small thumbnails of the
   files.
 
   Authors: [[User:Lupo]], January 2009; [[User:Ilmari Karonen]], April 2010
   License: Quadruple licensed GFDL, GPL, LGPL and Creative Commons Attribution 3.0 (CC-BY-3.0)
*/
 
if (wgCanonicalSpecialPageName == "Log") $(document).ready(function () {
    var maxThumbWidth = 70;
    var maxThumbHeight = 70;
 
    var apiBatchSize = 50;
    var maxPathLength = (/MSIE/.test(navigator.userAgent) ? 2048 : 4092 - mw.config.get('wgServer').length) - 100; // safety margin
 
    var content = document.getElementById("bodyContent") ||       // monobook & vector skins
                  document.getElementById("mw_contentholder") ||  // modern skin
                  document.getElementById("article");             // classic skins
    if (!content) return;
 
    var list = content.getElementsByTagName("ul")[0];
    if (!list) return;
    list.className = 'mw-search-results';
 
    // That's all that's needed for the pretty layout!  All code below is for the image thumbnails.
 
    // Get list of upload log entries, abort early if there are none.
    var uploads = getElementsByClassName(list, "li", "mw-logline-upload");
    if (!uploads || uploads.length == 0) return;
 
    // Find image links within each upload entry.  For simplicity, we assume that all links are in
    // canonical prefixed text form, and that all file links thus begin with ns6prefix.  Otherwise
    // we'd have to extract and normalize the namespace prefix and look for it in wgNamespaceIds.
    var ns6prefix = wgFormattedNamespaces["6"] + ":";
    var imageLocations = {};
    for (var i = 0; i < uploads.length; i++) {
        var links = uploads[i].getElementsByTagName("a");
        for (var j = 0; j < links.length; j++) {
            var title = links[j].title;
            if (!title || title.substring(0, ns6prefix.length) != ns6prefix) continue;
            // Skip any redlinks, links in log summaries and links to uploaders' user/talk/contribs/etc. pages
            for (var e = links[j]; title && e && e != uploads[i]; e = e.parentNode) {
                if ( /(^|\s)(new|comment|mw-userlink|mw-usertoollinks|mw-revdelundel-link|searchResultImage)(\s|$)/.test(e.className) ) title = null;
            }
            if (title) {
                if (!imageLocations[title]) imageLocations[title] = [];
                imageLocations[title].push(uploads[i]);
            }                 
        }
    }
    uploads = links = null;  // we don't need these NodeLists anymore
 
    // Callback function to show the thumbnails:
    window.prettyLogAddThumbnails = function (result) {
 
        if (result.error || !result.query || !result.query.pages)
            throw new Error("PrettyLog: unexpected API result:\n" + result.toSource());
 
        // hopefully we don't get any normalization, but just in case...
        if (result.query.normalized) {
            var norm = result.query.normalized;
            for (var i = 0; i < norm.length; i++) {
                imageLocations[norm[i].to] = imageLocations[norm[i].from].concat( imageLocations[norm[i].to] || [] );
            }
        }
 
        // now loop over the result and insert thumbs
        var pages = result.query.pages;
        for (var id in pages) {
            var title = pages[id].title;
            if (!title) continue;  // should not happen
 
            if (pages[id].imagerepository && pages[id].imagerepository == "shared")
                continue;  // don't show thumbnails for remote images (could happen if an image shadowing a Commons image is uploaded locally and deleted)
 
            var info = pages[id].imageinfo;
            if (!info || !info.length) continue;  // can happen if the image has been deleted, or if it wasn't an image at all
            info = info[0];
 
            if (!info.thumburl) {
                // KLUGE: for some reason, audio files sometimes get no thumburl; fix it here
                // TODO(?): there are more file type icons we could match to MIME types if needed
                if (/^(audio\/|application\/ogg$)/.test(info.mime)) {
                    info.thumburl = stylepath + "/common/images/icons/fileicon-ogg.png";
                } else {
                    info.thumburl = stylepath + "/common/images/icons/fileicon.png";  // generic fallback icon
                }
                info.thumbwidth = info.thumbheight = 120;  // all icons are currently 120x120
            }
 
            if (!info.thumbwidth || !info.thumbheight || !info.descriptionurl) continue;  // can't happen?
 
            // if the returned thumb is too large for some reason, scale it proportionately so it fits
            if (info.thumbheight > maxThumbHeight) {
                info.thumbwidth *= maxThumbHeight / info.thumbheight;
                info.thumbheight = maxThumbHeight;
            }
            if (info.thumbwidth > maxThumbWidth) {
                info.thumbheight *= maxThumbWidth / info.thumbwidth;
                info.thumbwidth = maxThumbWidth;
            }
 
            // if the URL is local, strip the hostname prefix (avoids needless external link icons on some browsers)
            if (info.descriptionurl.indexOf(mw.config.get('wgServer') + "/") === 0)
                info.descriptionurl = info.descriptionurl.substring(mw.config.get('wgServer').length);
 
            var loglines = imageLocations[title];
            if (!loglines) continue;  // should not happen
 
            for (var i = 0; i < loglines.length; i++) {
                // safety check: don't process the same line twice
                if (/^table$/i.test(loglines[i].firstChild.tagName)) continue;
 
                // create image and link elements for the thumbnail
                var img = document.createElement("img");
                img.src = info.thumburl;
                img.width = Math.round(info.thumbwidth);
                img.height = Math.round(info.thumbheight);
 
                var link = document.createElement("a");
                link.href = info.descriptionurl;
                link.title = title;
                link.className = "image";
                link.appendChild(img);
 
                // transform the contents of this logline into a table
                var tbl = document.createElement("table");
                tbl.className = "searchResultImage";
                var tr = tbl.insertRow(-1);
                tr.setAttribute("valign", "top");
 
                var td = document.createElement("td");
                td.width = maxThumbWidth + 10;
                td.setAttribute("align", "center");
                td.appendChild(link);
                tr.appendChild(td);
 
                td = document.createElement("td");
                while (loglines[i].firstChild) td.appendChild(loglines[i].firstChild);
                tr.appendChild(td);
 
                loglines[i].appendChild (tbl);
            }
        }

    };
 
    // Build array of unique image titles and URL-encode them.
    var images = [];
    for (var title in imageLocations) {
        if (typeof (title) == 'string') images.push( encodeURIComponent( title ) );
    }
 
    // Make the queries in batches, to avoid tripping API and URL length limits.
    var queryPrefix = wgScriptPath + "/api.php?format=json&callback=prettyLogAddThumbnails&action=query&maxage=3600&smaxage=3600&prop=imageinfo&iiprop=url%7Cmime&iiurlwidth="+maxThumbWidth+"&iiurlheight="+maxThumbHeight+"&titles=";
    while (images.length > 0) {
        var query = queryPrefix + images.shift();
        var n = 1;
        while (images.length > 0 && n < apiBatchSize && query.length + images[0].length + 3 <= maxPathLength) {
            query += "%7C" + images.shift(); n++;
        }
        mw.loader.load(query);
    }
});
 
//</source>