Difference between revisions of "MediaWiki:Gadget-QuickDiff.js"
Jump to navigation
Jump to search
(Created page with "→<nowiki> QDmodal - flexbox-based modal library CSS located at [[MediaWiki:Gadget-QDmodal.css]] @author OneTwoThreeFall @source <https://dev.fandom.com/wiki/QDmodal> @source <https://dev.fandom.com/wiki/MediaWiki:QDmodal.js>: →jslint browser, long, this: →global jQuery, mediaWiki: (function ($, mw) { "use strict"; var version = 20180212; if (mw.libs.QDmodal && mw.libs.QDmodal.version >= version) { return; }...") |
|||
Line 1: | Line 1: | ||
/* <nowiki> | /* <nowiki> | ||
QuickDiff - quickly view any diff link | |||
Modified to remove Wikia-specific i18n code, relies on [[MediaWiki:Gadget-QDmodal.js]] | |||
@author OneTwoThreeFall | @author OneTwoThreeFall | ||
@source <https://dev.fandom.com/wiki/ | @source <https://dev.fandom.com/wiki/QuickDiff> | ||
@source <https://dev.fandom.com/wiki/MediaWiki: | @source <https://dev.fandom.com/wiki/MediaWiki:QuickDiff/code.js> | ||
*/ | */ | ||
/*jslint browser, long | /*jslint browser, long */ | ||
/*global jQuery, mediaWiki */ | /*global jQuery, mediaWiki, dev */ | ||
(function ($, mw) { | (function ($, mw) { | ||
"use strict"; | "use strict"; | ||
// double-run protection | |||
if (window.quickDiffLoaded) { | |||
if ( | |||
return; | return; | ||
} | } | ||
window.quickDiffLoaded = true; | |||
var diffStylesModule = "mediawiki.action.history.diff"; | |||
var modal; | |||
var special = {}; | |||
// "Special:Diff/12345" and "Special:ComparePages" link detection | |||
function initSpecialPageStrings() { | |||
special.diffDefault = mw.util.getUrl("Special:Diff/"); | |||
special.compareDefault = mw.util.getUrl("Special:ComparePages"); | |||
var wiki = mw.config.get("wgDBname"); | |||
var | var storageKeyDiff = "QuickDiff-specialdiff_" + wiki; | ||
var storageKeyCompare = "QuickDiff-specialcompare_" + wiki; | |||
try { | |||
special.diff = localStorage.getItem(storageKeyDiff); | |||
special.compare = localStorage.getItem(storageKeyCompare); | |||
} catch (ignore) {} | |||
} | |||
if ( | if (special.diff && special.compare) { | ||
// using stored values - no need for api request | |||
return; | |||
} | } | ||
$.getJSON(mw.util.wikiScript("api"), { | |||
$ | action: "parse", | ||
format: "json", | |||
prop: "text", | |||
text: "<span class='diff'>[[Special:Diff/]]</span><span class='compare'>[[Special:ComparePages]]</span>", | |||
disablepp: "" // note: deprecated in MW 1.26, but needed for older versions | |||
}).done(function (data) { | |||
var $parsed = $(data.parse.text["*"]); | |||
special.diff = $parsed.find(".diff > a").attr("href"); | |||
special.compare = $parsed.find(".compare > a").attr("href"); | |||
try { | |||
localStorage.setItem(storageKeyDiff, special.diff); | |||
localStorage.setItem(storageKeyCompare, special.compare); | |||
} catch (ignore) {} | |||
}); | |||
} | } | ||
function getDiffTitle($diff) { | |||
var prevTitle = $diff.find("#mw-diff-otitle1 a").attr("title"); | |||
var currTitle = $diff.find("#mw-diff-ntitle1 a").attr("title"); | |||
if (prevTitle && prevTitle !== currTitle) { | |||
if ( | return "Differences between " + prevTitle + " and " + currTitle; | ||
} | } | ||
return "Differences: " + currTitle; | |||
} | |||
function loadDiff(url) { | |||
modal.show({ | |||
loading: true, | |||
title: !modal.visible && "Loading..." | |||
}); | |||
// add 'action=render' and 'diffonly' params to save some bytes on each request | |||
url.extend({ | |||
action: "render", | |||
diffonly: "1" | |||
}); | |||
// pass through 'bot' param for rollback links if it's in use on the current page | |||
if (mw.util.getParamValue("bot")) { | |||
url.extend({bot: "1"}); | |||
} | |||
$.when( | |||
$.get(url.getRelativePath()), | |||
mw.loader.using(diffStylesModule) | |||
).always(function (response) { | |||
delete url.query.action; | |||
delete url.query.diffonly; | |||
delete url.query.bot; | |||
var data = { | |||
buttons: [{ | |||
text: "open link", | |||
href: url.toString(), | |||
attr: {"data-disable-quickdiff": ""} | |||
}] | |||
}; | |||
var $diff; | |||
if (typeof response[0] === "string") { | |||
var $content = $(response[0]); | |||
$diff = $content.filter("table.diff, #mw-rev-deleted-no-diff"); | |||
if (!$diff.length) { | |||
// $content is a complete page - see if a diff can be found | |||
// needed for diffs from special pages as they ignore action=render URL parameter | |||
$diff = $content.find("table.diff"); | |||
} | |||
} | } | ||
if ($diff && $diff.length) { | |||
data.content = $diff; | |||
data.hook = "quickdiff.ready"; | |||
data.title = getDiffTitle($diff); | |||
} else { | |||
data.content = "Something went wrong while getting the page at " + url.toString() + "."; | |||
} | } | ||
modal.show(data); | |||
}); | |||
} | |||
function linkClickHandler(event) { | |||
// ignore clicks with modifier keys to avoid overriding browser features | |||
if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) { | |||
return; | |||
if ( | |||
} | } | ||
// ignore click if link has "data-disable-quickdiff" attribute set | |||
if (! | if (event.currentTarget.dataset.disableQuickdiff !== undefined) { | ||
return; | return; | ||
} | } | ||
var url = event.currentTarget.href; | |||
try { | |||
url = new mw.Uri(url); | |||
} catch (ignore) { | |||
// quit if url couldn't be parsed | |||
// it wouldn't be a link QuickDiff could handle anyway | |||
return; | |||
} | |||
// | // cross-domain requests not supported | ||
if ( | if (url.host !== location.hostname) { | ||
return; | |||
} | } | ||
// no fragment check is to ensure section links/collapsible trigger links on diff pages are ignored | |||
var hasDiffParam = url.query.diff !== undefined | |||
&& url.fragment === undefined; | |||
var isSpecialDiffLink = url.path.indexOf(special.diff) === 0 | |||
|| url.path.indexOf(special.diffDefault) === 0; | |||
var isSpecialCompareLink = url.path.indexOf(special.compare) === 0 | |||
|| url.path.indexOf(special.compareDefault) === 0; | |||
if (hasDiffParam || isSpecialDiffLink || isSpecialCompareLink) { | |||
event.preventDefault(); | |||
loadDiff(url); | |||
} | } | ||
} | |||
function init() { | |||
modal = new mw.libs.QDmodal("quickdiff-modal"); | |||
// full screen modal | |||
mw.util.addCSS("#quickdiff-modal { height: 100%; width: 100% }"); | |||
if ( | // diff styles module was renamed in MW 1.28 | ||
if (mw.loader.getState("mediawiki.diff.styles")) { | |||
diffStylesModule = "mediawiki.diff.styles"; | |||
} | } | ||
// attach to body for compatibility with ajax-loaded content | |||
// also, one attached event handler is better than hundreds! | |||
$(document.body).on("click.quickdiff", "a[href]", linkClickHandler); | |||
initSpecialPageStrings(); | |||
} | |||
init(); | |||
function | // collect action links (edit, undo, rollback, patrol) and add them to footer | ||
var | mw.hook("quickdiff.ready").add(function (modal) { | ||
// edit/undo links use "mw-rev-head-action" class on Wikia, | |||
// and "mw-diff-edit" or "-undo" class on MW 1.24+ | |||
var $buttons = modal.$content.find(".diff-ntitle").find( | |||
".mw-rev-head-action, .mw-diff-edit, .mw-diff-undo, .mw-rollback-link, .patrollink" | |||
).clone(); | |||
// remove text nodes (the brackets around each link) | |||
$buttons.contents().filter(function (ignore, element) { | |||
return element.nodeType === 3; | |||
}).remove(); | |||
); | |||
$buttons.find("a") | |||
.addClass("qdmodal-button") | |||
.attr("target", "_blank"); | |||
modal.$footer.append($buttons); | |||
}); | |||
}(jQuery, mediaWiki)); | }(jQuery, mediaWiki)); |
Latest revision as of 08:39, 16 February 2022
/* <nowiki> QuickDiff - quickly view any diff link Modified to remove Wikia-specific i18n code, relies on [[MediaWiki:Gadget-QDmodal.js]] @author OneTwoThreeFall @source <https://dev.fandom.com/wiki/QuickDiff> @source <https://dev.fandom.com/wiki/MediaWiki:QuickDiff/code.js> */ /*jslint browser, long */ /*global jQuery, mediaWiki, dev */ (function ($, mw) { "use strict"; // double-run protection if (window.quickDiffLoaded) { return; } window.quickDiffLoaded = true; var diffStylesModule = "mediawiki.action.history.diff"; var modal; var special = {}; // "Special:Diff/12345" and "Special:ComparePages" link detection function initSpecialPageStrings() { special.diffDefault = mw.util.getUrl("Special:Diff/"); special.compareDefault = mw.util.getUrl("Special:ComparePages"); var wiki = mw.config.get("wgDBname"); var storageKeyDiff = "QuickDiff-specialdiff_" + wiki; var storageKeyCompare = "QuickDiff-specialcompare_" + wiki; try { special.diff = localStorage.getItem(storageKeyDiff); special.compare = localStorage.getItem(storageKeyCompare); } catch (ignore) {} if (special.diff && special.compare) { // using stored values - no need for api request return; } $.getJSON(mw.util.wikiScript("api"), { action: "parse", format: "json", prop: "text", text: "<span class='diff'>[[Special:Diff/]]</span><span class='compare'>[[Special:ComparePages]]</span>", disablepp: "" // note: deprecated in MW 1.26, but needed for older versions }).done(function (data) { var $parsed = $(data.parse.text["*"]); special.diff = $parsed.find(".diff > a").attr("href"); special.compare = $parsed.find(".compare > a").attr("href"); try { localStorage.setItem(storageKeyDiff, special.diff); localStorage.setItem(storageKeyCompare, special.compare); } catch (ignore) {} }); } function getDiffTitle($diff) { var prevTitle = $diff.find("#mw-diff-otitle1 a").attr("title"); var currTitle = $diff.find("#mw-diff-ntitle1 a").attr("title"); if (prevTitle && prevTitle !== currTitle) { return "Differences between " + prevTitle + " and " + currTitle; } return "Differences: " + currTitle; } function loadDiff(url) { modal.show({ loading: true, title: !modal.visible && "Loading..." }); // add 'action=render' and 'diffonly' params to save some bytes on each request url.extend({ action: "render", diffonly: "1" }); // pass through 'bot' param for rollback links if it's in use on the current page if (mw.util.getParamValue("bot")) { url.extend({bot: "1"}); } $.when( $.get(url.getRelativePath()), mw.loader.using(diffStylesModule) ).always(function (response) { delete url.query.action; delete url.query.diffonly; delete url.query.bot; var data = { buttons: [{ text: "open link", href: url.toString(), attr: {"data-disable-quickdiff": ""} }] }; var $diff; if (typeof response[0] === "string") { var $content = $(response[0]); $diff = $content.filter("table.diff, #mw-rev-deleted-no-diff"); if (!$diff.length) { // $content is a complete page - see if a diff can be found // needed for diffs from special pages as they ignore action=render URL parameter $diff = $content.find("table.diff"); } } if ($diff && $diff.length) { data.content = $diff; data.hook = "quickdiff.ready"; data.title = getDiffTitle($diff); } else { data.content = "Something went wrong while getting the page at " + url.toString() + "."; } modal.show(data); }); } function linkClickHandler(event) { // ignore clicks with modifier keys to avoid overriding browser features if (event.altKey || event.ctrlKey || event.metaKey || event.shiftKey) { return; } // ignore click if link has "data-disable-quickdiff" attribute set if (event.currentTarget.dataset.disableQuickdiff !== undefined) { return; } var url = event.currentTarget.href; try { url = new mw.Uri(url); } catch (ignore) { // quit if url couldn't be parsed // it wouldn't be a link QuickDiff could handle anyway return; } // cross-domain requests not supported if (url.host !== location.hostname) { return; } // no fragment check is to ensure section links/collapsible trigger links on diff pages are ignored var hasDiffParam = url.query.diff !== undefined && url.fragment === undefined; var isSpecialDiffLink = url.path.indexOf(special.diff) === 0 || url.path.indexOf(special.diffDefault) === 0; var isSpecialCompareLink = url.path.indexOf(special.compare) === 0 || url.path.indexOf(special.compareDefault) === 0; if (hasDiffParam || isSpecialDiffLink || isSpecialCompareLink) { event.preventDefault(); loadDiff(url); } } function init() { modal = new mw.libs.QDmodal("quickdiff-modal"); // full screen modal mw.util.addCSS("#quickdiff-modal { height: 100%; width: 100% }"); // diff styles module was renamed in MW 1.28 if (mw.loader.getState("mediawiki.diff.styles")) { diffStylesModule = "mediawiki.diff.styles"; } // attach to body for compatibility with ajax-loaded content // also, one attached event handler is better than hundreds! $(document.body).on("click.quickdiff", "a[href]", linkClickHandler); initSpecialPageStrings(); } init(); // collect action links (edit, undo, rollback, patrol) and add them to footer mw.hook("quickdiff.ready").add(function (modal) { // edit/undo links use "mw-rev-head-action" class on Wikia, // and "mw-diff-edit" or "-undo" class on MW 1.24+ var $buttons = modal.$content.find(".diff-ntitle").find( ".mw-rev-head-action, .mw-diff-edit, .mw-diff-undo, .mw-rollback-link, .patrollink" ).clone(); // remove text nodes (the brackets around each link) $buttons.contents().filter(function (ignore, element) { return element.nodeType === 3; }).remove(); $buttons.find("a") .addClass("qdmodal-button") .attr("target", "_blank"); modal.$footer.append($buttons); }); }(jQuery, mediaWiki));