MediaWiki:Gadget-U2693.js
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.
/* jshint undef:true, latedef:true, shadow:true, boss:true, scripturl:true */
/* global mw, jQuery */
// <nowiki>
"use strict";
mw.loader.using(["mediawiki.util"]).then(() =>
$(function() {
var curRevisionId = mw.config.get("wgCurRevisionId");
function createAnchorLink(label, href, wikilink, title) {
var span = document.createElement("span");
var link = document.createElement("a");
link.href = href;
link.addEventListener(
"click",
function(ev) {
ev.preventDefault();
// IE
if (window.clipboardData && window.clipboardData.setData) {
window.clipboardData.setData("text", wikilink);
mw.util.jsMessage("Wikitext copied to the clipboard.");
return;
}
// XXX: there is a brand new shiny ClipboardEvent API, but I could not get it to work on my browser.
// plus, there is no graceful fallback if it fails to work. going back to good ol' prompt().
prompt("Hit Ctrl-C to copy this to your clipboard", wikilink);
},
false
);
link.appendChild(document.createTextNode(label));
link.title = title;
span.appendChild(document.createTextNode("["));
span.appendChild(link);
span.appendChild(document.createTextNode("]"));
span.className = "mw-editsection-like anchor-gadget-link";
return span;
}
// XXX: not ideal; it may over-unescape things, but it usually works as intended
function unescapeAnchor(anchor) {
anchor = anchor.replace(/_/g, " ");
try {
return decodeURIComponent(
anchor.replace(/\.([0-9A-F][0-9A-F])/g, "%$1")
);
} catch (e) {
return anchor;
}
}
function forEachHeader(callback) {
var headers = document.querySelectorAll(
".mw-heading > h2, .mw-heading > h3, .mw-heading > h4, .mw-heading > h5, .mw-heading > h6, .mw-headline"
);
for (var i = 0; i < headers.length; ++i) {
var links = headers[i].parentNode.getElementsByTagName("a");
var title = null;
for (var j = 0; j < links.length; ++j) {
try {
var u = new URL(links[j].href);
if (
u.hostname === location.host &&
u.pathname === mw.config.get("wgScript") &&
u.searchParams.get("action") === "edit" &&
!u.searchParams.get("redlink")
) {
title = new mw.Title(u.searchParams.get("title"));
}
} catch (e) {
/* screw it */
}
}
if (!title) continue;
callback(headers[i], title);
}
}
function getRevInfo(oldid, callback) {
// XXX: of course I have it right on the page, but I cannot rely on it being in any particular format.
// hence wasting bandwidth on an API request.
mw.loader.using(["mediawiki.api", "mediawiki.util"], function() {
var api = new mw.Api();
api
.get({
action: "query",
pageids: mw.config.get("wgArticleId"),
prop: "revisions",
rvprop: "user|timestamp",
rvstartid: oldid,
rvlimit: 1,
})
.then(function(result) {
var revobj =
result.query.pages[mw.config.get("wgArticleId")].revisions[0];
callback(revobj);
});
});
}
function createUnsignedLink(revobj) {
var userpart =
(mw.util.isIPv4Address(revobj.user) ||
mw.util.isIPv6Address(revobj.user) ?
"{{unsigned-ip|" :
"{{unsigned|") + revobj.user;
var datepart = "}}";
var m;
if (
(m = /^(\d+)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)Z$/.exec(
revobj.timestamp
))
) {
var monthNames = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
datepart =
"|" +
m[4] +
":" +
m[5] +
", " +
m[3].replace(/^0+/, "") +
" " +
monthNames[parseInt(m[2], 10) - 1] +
" " +
m[1] +
" (UTC)}}";
}
return createAnchorLink(
"✎",
"javascript:void window.warranty",
userpart + datepart,
"{{unsigned}}"
);
}
if (mw.config.get("wgAction") !== "view") return;
mw.util.addCSS(
".anchor-gadget-link { -moz-user-select: none; -webkit-user-select: none; -ms-user-select: none; user-select: none; }"
);
if (mw.util.getParamValue("diff")) {
// viewing a diff
var oldid, newid;
var ot = document.getElementById("mw-diff-otitle1");
var nt = document.getElementById("mw-diff-ntitle1");
if (ot) {
ot = new URL(ot.getElementsByTagName("a")[0].href);
oldid = ot.searchParams.get("oldid");
}
if (nt) {
nt = new URL(nt.getElementsByTagName("a")[0].href);
newid = nt.searchParams.get("oldid");
}
document
.getElementById("firstHeading")
.appendChild(
createAnchorLink(
"⚓",
mw.config.get("wgScript") + "?oldid=" + oldid + "&diff=" + newid,
"[[Special:Diff/" + oldid + "/" + newid + "]]",
"Link to this diff"
)
);
if (
document.getElementsByClassName("diffmulti").length === 0 &&
mw.config.get("wgArticleId")
) {
getRevInfo(newid, function(revobj) {
document
.getElementById("firstHeading")
.appendChild(createUnsignedLink(revobj));
});
}
} else if (mw.util.getParamValue("oldid") || curRevisionId) {
// viewing an old page revision
var oldid = mw.util.getParamValue("oldid") || curRevisionId;
document
.getElementById("firstHeading")
.appendChild(
createAnchorLink(
"⚓",
mw.config.get("wgScript") + "?oldid=" + oldid,
"[[Special:Permalink/" + oldid + "]]",
"Link to this revision"
)
);
getRevInfo(oldid, function(revobj) {
document
.getElementById("firstHeading")
.appendChild(createUnsignedLink(revobj));
});
}
if (
mw.config.get("wgRevisionId") === curRevisionId &&
// 100 = appendix, 114 = citations
[0, 100, 114].indexOf(mw.config.get("wgNamespaceNumber")) === -1
) {
forEachHeader(function(header, title) {
var anchorLink = createAnchorLink(
"⚓",
mw.util.getUrl(title.getPrefixedDb()) + "#" + header.id,
"[[" +
title.getPrefixedText() +
"#" +
unescapeAnchor(header.id) +
"]]"
);
var editSectionLink =
header.parentNode.querySelector(".mw-editsection");
if (editSectionLink) {
header.parentNode.insertBefore(
anchorLink,
editSectionLink.nextSibling
);
} else {
header.parentNode.appendChild(anchorLink);
}
});
}
})
);
// </nowiki>