User:Awesome Aasim/linkinfo.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
![]() | This user script seems to have a documentation page at User:Awesome Aasim/linkinfo and an accompanying .css page at User:Awesome Aasim/linkinfo.css. |
if (!userAndAPageInfoLoaded) {
var userAndAPageInfoLoaded = true;
(function() {
$(document).ready(async function() {
function isIP(text) {
return mw.util.isIPv6Address(text) || mw.util.isIPv4Address(text);
}
var user, page, link;
mw.loader.load("https://en.wikipedia.org/wiki/User:Awesome_Aasim/linkinfo.css?action=raw&ctype=text/css", "text/css");
mw.loader.using(['oojs-ui-core', 'oojs-ui-widgets', 'oojs-ui.styles.icons-content', 'oojs-ui.styles.icons-alerts', 'oojs-ui.styles.icons-interactions', 'oojs-ui.styles.icons-moderation', 'oojs-ui.styles.icons-editing-core', 'oojs-ui.styles.icons-editing-functions', 'oojs-ui.styles.icons-editing-advanced', 'oojs-ui.styles.icons-user', 'oojs-ui.styles.icons-layout', 'oojs-ui.styles.icons-accessibility'], async function() {
const OptWidget = OO.ui.MenuOptionWidget;
// below adapted partly from Microsoft Copilot
// Create a placeholder div where the custom context menu will attach
const $container = $('<div class="linkinfo">').css({ position: 'absolute', zIndex: 10000 }).appendTo( document.body );
// Define menu items
const select = new OO.ui.SelectWidget();
const menu = new OO.ui.MenuLayout({
menuPanel: new OO.ui.PanelLayout({padded: true, scrollable: true, expanded: true})
});
menu.$menu.append(select.$element);
// Create popup widget to wrap the menu
const popup = new OO.ui.PopupWidget( {
$content: menu.$menu,
autoClose: true,
head: false,
tail: false,
anchor: false
} );
$container.append( popup.$element );
$container.css({
'user-select': 'none',
'-webkit-user-select': 'none',
'-moz-user-select': 'none',
'-ms-user-select': 'none'
});
$(document).on("contextmenu", "a", async function(e) {
function show() {
popup.setSize(null, null, false);
popup.toggle(true);
let puWidth = popup.$element.width();
let puHeight = popup.$element.height();
let puPosition = popup.$element.position();
let leftEdge = puPosition.left;
let rightEdge = puPosition.left + puWidth;
let topEdge = puPosition.top;
let bottomEdge = puPosition.top + puWidth;
let puOffset = popup.$element.offset();
let leftEdgeOS = puOffset.left - $(window).scrollLeft();
let rightEdgeOS = puOffset.left + puWidth - $(window).scrollLeft();
let topEdgeOS = puOffset.top - $(window).scrollTop();
let bottomEdgeOS = puOffset.top + puHeight - $(window).scrollTop();
$container.css({ top: e.pageY + 'px' });
if (puHeight < menu.$menu.height()) {
if (Math.abs(bottomEdgeOS - window.innerHeight) > Math.abs(topEdgeOS)) {
$container.css({ top: $container.position().top + (menu.$menu.height() - puHeight) + 1 + 'px' });
} else {
$container.css({ top: $container.position().top - (menu.$menu.height() - puHeight) - 1 + 'px' });
}
popup.toggle(false);
popup.computePosition();
popup.setSize(null, null, false);
popup.toggle(true);
// popup.setSize(null, Math.min(menu.$menu.height(), window.innerHeight), false);
}
if (window.innerWidth - e.pageX < puWidth) {
$container.css({ left: e.pageX - rightEdge + 'px' });
} else {
$container.css({ left: e.pageX - leftEdge + 'px' });
}
puOffset = popup.$element.offset();
leftEdgeOS = puOffset.left - $(window).scrollLeft();
rightEdgeOS = puOffset.left + puWidth - $(window).scrollLeft();
topEdgeOS = puOffset.top - $(window).scrollTop();
bottomEdgeOS = puOffset.top + puHeight - $(window).scrollTop();
if (rightEdgeOS >= window.innerWidth || leftEdgeOS <= 0 || bottomEdgeOS >= window.innerHeight || topEdgeOS <= 0) {
$container.css({ top: $(window).scrollTop() + 'px', left: window.innerWidth / 2 + $(window).scrollLeft() + 'px' });
popup.toggle(false);
popup.computePosition();
popup.setSize(null, null, false);
popup.toggle(true);
}
puWidth = popup.$element.width();
if (puWidth >= window.innerWidth / 2) {
select.addItems([
new OptWidget({ data: "close", label: "Close menu", icon: "close" })
], 0);
}
}
if ($(this).data("nolinkinfo")) {
return;
}
popup.toggle( false ); // Hide if already shown
let url = new URL($(this).attr("href"), location.origin);
if (url.origin != location.origin || $(this).hasClass("external") || $(this).hasClass("extiw")) {
return;
}
let pageName;
if (url.pathname.search(mw.config.get("wgArticlePath").replace("$1", "")) != 0) {
pageName = url.searchParams.get("title");
} else {
pageName = url.pathname.substring(mw.config.get("wgArticlePath").replace("$1", "").length, url.pathname.length);
}
if (!pageName) {
return;
}
let title = new mw.Title(decodeURI(pageName));
if (title.getNamespaceId() < 0) {
return;
}
e.preventDefault();
$container.css({ top: e.pageY + 'px', left: e.pageX + 'px' });
link = url;
select.clearItems();
select.addItems([
new OptWidget({ data: "newtab", label: "Open in new tab", icon: "newWindow" })
]);
select.addItems([
new OptWidget({ data: "copylink", label: "Copy link", icon: "link" })
]);
if (window.getSelection().toString()) {
select.addItems([
new OptWidget({ data: "copy", label: "Copy", icon: "copy" })
]);
}
show();
var showUserLinks = title.getNamespaceId() == 2 || title.getNamespaceId() == 3;
let dataQuery = {
"action": "query",
"format": "json",
"meta": "userinfo",
"uiprop": "rights",
"prop": "info",
"inprop": "displaytitle|protection|subjectid|talkid|associatedpage",
"intestactions": "edit|move|delete|undelete|protect",
"titles": title.getPrefixedText(),
"formatversion": 2
};
if (showUserLinks) {
let user;
if (!isIP(title.getMainText()) || title.getNamespaceId() == 3) {
user = title.getMainText().split("/")[0];
} else {
user = title.getMainText();
}
dataQuery = Object.assign(dataQuery, {
"list": "users",
"ususers": user,
"usprop": "blockinfo|emailable|groups|implicitgroups|cancreate|groupmemberships"
});
}
let data;
try {
data = await $.get(mw.config.get('wgScriptPath') + '/api.php', dataQuery);
} catch (e) {
let $newA = $(this).clone();
$newA.data("nolinkinfo", true);
$newA.wrapAll("<span/>");
select.addItems([
new OptWidget({ label: $("<hr>"), disabled: true }),
new OptWidget({ label: $newA.parent().prepend("Original link: "), disabled: true })
]);
show();
return;
}
if (data.error) {
select.addItems([
new OptWidget({ label: $("<hr>"), disabled: true }),
new OptWidget({ label: "Error: " + data.error.info, disabled: true })
]);
let $newA = $(this).clone();
$newA.data("nolinkinfo", true);
$newA.wrapAll("<span/>");
select.addItems([
new OptWidget({ label: $("<hr>"), disabled: true }),
new OptWidget({ label: $newA.parent().prepend("Original link: "), disabled: true })
]);
show();
return;
}
page = data.query.pages[0];
let deletedrevs = [];
if (page.actions.undelete) {
deletedrevs = await $.get(mw.config.get("wgScriptPath") + "/api.php", {
action: "query",
format: "json",
list: "deletedrevs",
title: page.title,
"formatversion": 2
});
deletedrevs = deletedrevs.query.deletedrevisions || [];
}
popup.toggle(false);
select.addItems([
new OptWidget({ label: $("<hr>"), disabled: true })
]);
function addPrimaryPageLinks() {
select.addItems([
new OptWidget({ data: "pageview", label: "View", flags: "progressive", icon: "eye" })
]);
select.addItems([
new OptWidget({ data: "pagelink", label: "Copy as wikilink", icon: "wikiText" })
]);
if (page.ns % 2 == 0) {
select.addItems([
new OptWidget({ data: "pageassoc", label: "Discuss", icon: "speechBubbles" })
]);
} else {
select.addItems([
new OptWidget({ data: "pageassoc", label: "View primary", icon: "article" })
]);
}
select.addItems([
new OptWidget({ data: "pagelogs", label: "Page logs", icon: "viewDetails" })
]);
}
if (showUserLinks) {
user = data.query.users[0];
select.addItems([
new OptWidget({ label: "User options: " + user.name, disabled: true })
]);
if (!user.missing && (!user.invalid || isIP(user.name))) {
if (user.name.split("/").length == 1) {
if (!isIP(user.name)) {
select.addItems([
new OptWidget({ data: "userpage", label: "Profile", flags: "progressive", icon: "userAvatar" }),
new OptWidget({ data: "userlink", label: "Copy mention", icon: "wikiText" }),
new OptWidget({ data: "usertalk", label: "Message", icon: "userTalk" })
]);
} else {
select.addItems([
new OptWidget({ data: "usertalk", label: "Message", flags: "progressive", icon: "userTalk" })
]);
}
}
select.addItems([
new OptWidget({ data: "usercontribs", label: "Contributions", icon: "userContributions" }),
new OptWidget({ data: "userperformlogs", label: "User logs", icon: "recentChanges" }),
new OptWidget({ data: "usertargetlogs", label: "Target logs", icon: "viewDetails" })
]);
if (user.emailable && data.query.userinfo.rights.includes("sendemail")) {
select.addItems([
new OptWidget({ data: "useremail", label: "Email", icon: "message" })
]);
}
if (data.query.userinfo.rights.includes("block")) {
if (user.blockid) {
select.addItems([
new OptWidget({ data: "userblock", label: "Change block", flags: "destructive", icon: "block" }),
new OptWidget({ data: "userunblock", label: "Unblock", flags: "destructive", icon: "unBlock" })
]);
} else {
select.addItems([
new OptWidget({ data: "userblock", label: "Block", flags: "destructive", icon: "block" })
]);
}
}
if (!isIP(user.name)) {
select.addItems([
new OptWidget({ data: "userroles", label: "User roles", icon: "userRights" }),
new OptWidget({ data: "userid", label: "Copy user ID", icon: "markup" })
]);
}
select.addItems([
new OptWidget({ label: $("<hr>"), disabled: true })
]);
}
select.addItems([
new OptWidget({ label: "Page options: " + page.title, disabled: true })
]);
if (page.title.split("/").length != 1) {
addPrimaryPageLinks();
} else if (page.ns % 2 == 1) {
select.addItems([
new OptWidget({ data: "pagelogs", label: "Page logs", icon: "viewDetails" })
]);
}
}
if (!showUserLinks) {
select.addItems([
new OptWidget({ label: "Page options: " + page.title, disabled: true })
]);
addPrimaryPageLinks();
}
if (page.redirect) {
select.addItems([
new OptWidget({ data: "pageviewredir", label: "View redirect", icon: "articleRedirect" })
]);
}
select.addItems([
new OptWidget({ data: "pageinfo", label: "Page information", icon: "info" })
]);
if (page.actions.edit) {
if (page.missing) {
select.addItems([
new OptWidget({ data: "pageedit", label: "Create", icon: "articleAdd" })
]);
} else {
select.addItems([
new OptWidget({ data: "pageedit", label: "Edit", icon: "edit" })
]);
}
} else {
if (!page.missing) {
select.addItems([
new OptWidget({ data: "pageedit", label: "View source", icon: "editLock" })
]);
}
}
if (!page.missing) {
select.addItems([
new OptWidget({ data: "pagehist", label: "History", icon: "history" })
]);
if (page.actions.move) {
select.addItems([
new OptWidget({ data: "pagemove", label: "Move", icon: "literal" })
]);
}
if (page.actions.delete) {
select.addItems([
new OptWidget({ data: "pagedel", label: "Delete", "flags": "destructive", icon: "trash" })
]);
}
} else {
if (page.actions.undelete && deletedrevs.length > 0) {
select.addItems([
new OptWidget({ data: "pageundel", label: "Restore", "flags": "destructive", icon: "restore" })
]);
}
}
if (page.actions.protect) {
if (page.protection.length > 0) {
select.addItems([
new OptWidget({ data: "pageprot", label: "Change or Remove Protection", icon: "unLock" })
]);
} else {
select.addItems([
new OptWidget({ data: "pageprot", label: "Protect", icon: "lock" })
]);
}
}
if (!page.missing) {
select.addItems([
new OptWidget({ data: "pageid", label: "Copy page ID", icon: "markup" })
]);
}
let $newA = $(this).clone();
$newA.data("nolinkinfo", true);
$newA.wrapAll("<span/>");
select.addItems([
new OptWidget({ label: $("<hr>"), disabled: true }),
new OptWidget({ label: $newA.parent().prepend("Original link: "), disabled: true })
]);
show();
});
$(document).on("scroll", function() {
popup.toggle( false );
});
select.on( 'choose', async function (item) {
let data = item.getData();
switch (data) {
case "close":
popup.toggle( false );
break;
case "newtab":
popup.toggle( false );
window.open(link);
break;
case "copylink":
popup.toggle( false );
await navigator.clipboard.writeText(link.toString());
break;
case "copy":
popup.toggle( false );
await document.execCommand("copy");
break;
case "userpage":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `User:${user.name}`);
break;
case "userlink":
popup.toggle( false );
await navigator.clipboard.writeText(`@[[${mw.config.get("wgFormattedNamespaces")[2]}:${user.name}|${user.name}]]`);
break;
case "usertalk":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `User_talk:${user.name}`);
break;
case "usercontribs":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `Special:Contributions/${user.name}`);
break;
case "userperformlogs":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `Special:Log/${user.name}`);
break;
case "usertargetlogs":
popup.toggle( false );
location.href = (function() {
var url = new URL(location.origin);
url.pathname = mw.config.get("wgScriptPath") + "/index.php";
url.searchParams.set("title", "Special:Log");
url.searchParams.set("page", `User:${user.name}`);
return url;
})();
break;
case "useremail":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `Special:Email/${user.name}`);
break;
case "userblock":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `Special:Block/${user.name}`);
break;
case "userunblock":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `Special:Unblock/${user.name}`);
break;
case "userroles":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `Special:UserRights/${user.name}`);
break;
case "userid":
popup.toggle( false );
await navigator.clipboard.writeText(user.userid);
break;
case "pageview":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", page.title);
break;
case "pageassoc":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", page.associatedpage);
break;
case "pagelink":
popup.toggle( false );
await navigator.clipboard.writeText(`[[${page.title}]]`);
break;
case "pagelogs":
popup.toggle( false );
location.href = (function() {
var url = new URL(location.origin);
url.pathname = mw.config.get("wgScriptPath") + "/index.php";
url.searchParams.set("title", "Special:Log");
url.searchParams.set("page", page.title);
return url;
})();
break;
case "pageinfo":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `Special:PageInfo/${page.title}`);
break;
case "pageviewredir":
popup.toggle( false );
location.href = (function() {
var url = new URL(location.origin);
url.pathname = mw.config.get("wgScriptPath") + "/index.php";
url.searchParams.set("title", page.title);
url.searchParams.set("redirect", "no");
return url;
})();
break;
case "pageedit":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `Special:EditPage/${page.title}`);
break;
case "pagehist":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `Special:History/${page.title}`);
break;
case "pagemove":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `Special:MovePage/${page.title}`);
break;
case "pagedel":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `Special:DeletePage/${page.title}`);
break;
case "pageundel":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `Special:Undelete/${page.title}`);
break;
case "pageprot":
popup.toggle( false );
location.href = mw.config.get("wgArticlePath").replace("$1", `Special:ProtectPage/${page.title}`);
break;
case "pageid":
popup.toggle( false );
await navigator.clipboard.writeText(page.pageid);
break;
}
});
});
});
})();
}