User:HarJIT/portletnotifyshim.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.
//// A script to fix some userscript or gadget compatibility issues with non-Wikimedia MediaWiki wikis.
// This may be useful if your Wikia, ShoutWiki or other non-Wikimedia user-JS loads Wikipedia, Commons,
// etc. userscripts or gadgets and they run into incompatibilities.
//
// Feature shims carried out by this script:
//
// * Implements mw.util.addPortletLink(...) toolbar/toolbox addition functionality for third-party
// MediaWiki skins which either do not supply a addPortletLink implementation, or supply one which
// has not been ported to work with that skin.
// * Implements mw.notify and re-implements mw.util.jsMessage (jsMsg) for Wikia. (Note: because Wikia
// seems to have phagocytosed their mw.notify support from Gamepedia as of late, this part probably
// no longer actually does anything.)
//
// Note the following caveats:
//
// * Use at your own risk (I am not selling this and guarantee neither safety nor fitness).
// * Although it is possible to use this when logged out, i.e. from Greasemonkey, certain
// functionality (notably the Oasis toolbar) may only exist to begin with if you're logged in.
// Similarly, p-cactions only exists in CologneBlue if you have edit perms on the current page.
// * Portlets presently working: p-personal, p-tb, p-cactions, p-navigation.
// * Skins which presently should be working: Aether, Aurora, Carbon, CarbonGreen, Chameleon,
// Cosmos, Exvius, FandomDesktop, GreyStuff, Hydra, HydraDark, Monaco, Nimbus, Nostalgia, Oasis,
// Onyx, Plurple, PlurpleDark, Standard, Truglass.
// * Note that this has only been tested on certain deployed versions of those skins.
// * Last tested December 2019 on Wikia, Shoutwiki, DoomWiki, Halopedia, Uncyclopedia.
// * Last tested January 2020 on FTBWiki.org, Nostalgia Wikipedia.
// * Last tested April 2021 on Gamepedia, TFWiki.net.
// * Skins which this shouldn't be necessary for:
// * Wikimedia skins: Monobook, Vector, Chick, CologneBlue, Modern, MySkin, Timeless.
// * Others which already include their own compatible implementations of addPortletLink:
// Bouquet, DeskMessMirrored, Dusk, DuskToDawn, Gamepress, MonacoBook, Simple
// (or anything which is simply a Monobook modification).
// * Known skins not currently provided for:
// * Skins used for mobile sites: Citizen, FandomMobile, Minerva (including MinervaNeue),
// WikiaMobile, WPTouch.
// * addPortletLink absent: […]
// * addPortletLink inadequate: […]
//
// Skin-specific caveats:
//
// * Oasis:
// * p-tb are added to "my tools" menu, very-short-label p-cactions add to the tool bar itself.
// * Labels longer than 3 characters will be added to the "my tools" menu either way, because:
// * The small-screen overflow system does not work on labels added to the bar (they just
// disappear). Having tried to get this working, I've given up.
// * These added options disappear until refresh if you use the customise feature on the
// toolbar. Not sure what I can do about that.
// * Too many p-navigation items just extend off the edge of the screen, such that they cannot
// be accessed.
// * FandomDesktop: includes several copies of the p-navigation equivalent, which become visible
// at different screen sizes, and depending on whether the viewport is panned to the top of the
// page or scrolled further down it. Only the link from one of these can be returned, so any
// application of event handlers by invoking code will only apply to that one. Caveat about
// the Oasis toolbar customisation feature probably applies here also.
// * Onyx: lacking a "my tools" menu, p-tb and p-cactions are both added to the tool bar itself.
// * Aurora: since the page/source/talk/history use custom icons, both p-tb and p-cactions are
// added to the "Page tools" menu from the bar to the right, not the actions bar to the left.
// * Nostalgia: since some of the portlets' functions are duplicated in multiple parts of the
// page (e.g. the p-cactions edit/talk/history in both header and footer), links often have to
// be added in multiple locations. Only one of these can be returned, so anything which the
// invoking code does to the portlet links after they're added (e.g. custom event handlers)
// will only be applied to that one.
//
// Basic usage, has some limitations (cannot guarantee running before dependent code):
// mw.loader.load("//meta.wikimedia.org/w/index.php?action=raw&ctype=text/javascript&title=User:HarJIT/portletnotifyshim.js");
//
// It's more reliable to put dependent code in a callback:
// $.getScript("//meta.wikimedia.org/w/index.php?action=raw&ctype=text/javascript&title=User:HarJIT/portletnotifyshim.js", function(){
// // do or load stuff that creates tabs ...
// });
//
// Canonical: [[m:User:HarJIT/portletnotifyshim.js]]
// Unstable: [[m:User:HarJIT/portletnotifyshim.js/sb.js]]
if(function(){
// No onload mechanism as (a) this must run before all onload callbacks which might use addPortletLink
// and (b) it isn't needed as the DOM is only used upon addPortletLink actually being called.
var $ = jQuery; // No reason to suspect PrototypeJS to be loaded, but be sure nonetheless.
//////////////////////////////////////////////////////////////////////////////////////////////////////
// addPortletLink
// Favour the one in mw.util (sometimes they differ, e.g. on tfwiki.net, in which case the mw.util one is the correct one).
var save_mwutiladdPortletLink = (typeof addPortletLink != "undefined" && addPortletLink != null)?(addPortletLink):(function(){});
save_mwutiladdPortletLink = (typeof mw.util.addPortletLink != "undefined" && mw.util.addPortletLink != null)?(mw.util.addPortletLink):(save_mwutiladdPortletLink);
var genAnc = function (ar) {
var anc = document.createElement("a");
anc.setAttribute("href", ar[1]); // href (ar[0], ar[1], ar[2] were formal params)
if (typeof ar[3] != "undefined" && ar[3] !== null) {
anc.setAttribute("data-name", ar[3]);
anc.setAttribute("id", ar[3]);
};
if (typeof ar[4] != "undefined" && ar[4] !== null) {
anc.setAttribute("title", ar[4]);
};
if (typeof ar[5] != "undefined" && ar[5] !== null) {
anc.setAttribute("accesskey", ar[5]);
};
return anc;
};
if (mw.config.get("skin") == "oasis" && !mw.config.get("HarJIT-tabshim-loaded")) {
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var ovf; var anc;
var labeltext = document.createTextNode(text);
if (portletId == "p-cactions" || portletId == "p-tb") {
ovf = document.createElement("li");
ovf.setAttribute("class", "overflow");
var mtm = document.getElementById("my-tools-menu");
if (text.length < 4 && portletId == "p-cactions") {
mtm.parentNode.parentNode.insertBefore(ovf, mtm.parentNode);
} else {
mtm.appendChild(ovf);
};
anc = genAnc(arguments);
} else if (portletId == "p-navigation") {
var udrop = document.getElementsByClassName("wds-community-header__local-navigation")[0];
var ulst = udrop.getElementsByClassName("wds-tabs")[0];
var ivf = document.createElement("li");
ulst.appendChild(ivf);
ivf.setAttribute("class", "wds-tabs__tab");
ovf = document.createElement("div");
ivf.appendChild(ovf);
ovf.setAttribute("class", "wds-tabs__tab-label");
anc = genAnc(arguments);
anc.setAttribute("class", "wds-global-navigation__dropdown-link");
var spa = document.createElement("span");
spa.appendChild(labeltext);
labeltext = spa;
} else if (portletId == "p-personal") {
ovf = document.createElement("li");
var udrop = document.getElementsByClassName("wds-global-navigation__user-menu")[0];
var ulst = udrop.getElementsByClassName("wds-list")[0];
ulst.appendChild(ovf);
anc = genAnc(arguments);
anc.setAttribute("class", "wds-global-navigation__dropdown-link");
} else {
return save_mwutiladdPortletLink.apply(this, arguments);
};
ovf.appendChild(anc);
anc.appendChild(labeltext);
return ovf;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "fandomdesktop" && !mw.config.get("HarJIT-tabshim-loaded")) {
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var ovf; var anc;
var labeltext = document.createTextNode(text);
if (portletId == "p-cactions") {
ovf = document.createElement("li");
ovf.setAttribute("class", "overflow");
var mtm = document.querySelector(".page-header__actions ul");
mtm.appendChild(ovf);
anc = genAnc(arguments);
ovf.appendChild(anc);
anc.appendChild(labeltext);
} else if (portletId == "p-tb") {
ovf = document.createElement("li");
ovf.setAttribute("class", "overflow");
var mtm = document.getElementById("my-tools-menu");
mtm.appendChild(ovf);
anc = genAnc(arguments);
ovf.appendChild(anc);
anc.appendChild(labeltext);
} else if (portletId == "p-navigation") {
var disputes = arguments;
$(".fandom-community-header__local-navigation .wds-tabs").toArray().map(function (ulst) {
var moreMenus = ulst.getElementsByClassName("more-menu");
if (moreMenus.length) {
var myul = moreMenus[0].getElementsByClassName("wds-list")[0];
ovf = document.createElement("li");
myul.appendChild(ovf);
anc = genAnc(disputes);
ovf.appendChild(anc);
anc.appendChild(document.createTextNode(text));
} else {
var ivf = document.createElement("div");
ulst.appendChild(ivf);
ivf.setAttribute("class", "wds-dropdown");
ovf = document.createElement("div");
ivf.appendChild(ovf);
ovf.setAttribute("class", "wds-tabs__tab-label first-level-item");
anc = genAnc(disputes);
ovf.appendChild(anc);
var spa = document.createElement("span");
anc.appendChild(spa);
spa.appendChild(document.createTextNode(text));
}
console.log(myul || ulst);
});
} else if (portletId == "p-personal") {
ovf = document.createElement("li");
var udrop = document.querySelector(".global-navigation__bottom > .wds-dropdown .wds-dropdown__content");
var ulst = udrop.getElementsByClassName("wds-list")[0];
ulst.appendChild(ovf);
anc = genAnc(arguments);
ovf.appendChild(anc);
anc.appendChild(labeltext);
} else {
return save_mwutiladdPortletLink.apply(this, arguments);
};
return ovf;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "aurora" && !mw.config.get("HarJIT-tabshim-loaded")) {
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var ovf; var anc;
if (portletId == "p-cactions" || portletId == "p-tb") {
portletId = "p-tools";
}
ovf = document.createElement("li");
var ulst = document.getElementById(portletId);
ulst.appendChild(ovf);
anc = genAnc(arguments);
ovf.appendChild(anc);
anc.appendChild(document.createTextNode(text));
return ovf;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "truglass" && !mw.config.get("HarJIT-tabshim-loaded")) {
var truglassAria = function () {
if (!mw.config.get("HarJIT-tabshim-aria")) {
mw.config.set("HarJIT-tabshim-aria", 1);
// Yes really, truglass uses layout tables.
$("table.fullwidth").toArray().map(function (e) {
e.setAttribute("role", "presentation");
});
$("div.sbmodule").toArray().map(function (e) {
e.setAttribute("role", "navigation");
});
document.getElementById("realcontent").setAttribute("role", "main");
}
}
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var ovf; var anc;
if (portletId == "p-cactions") {
ovf = document.createElement("span");
var mtm = $(".cbar td").toArray()[0]
mtm.appendChild(document.createTextNode("\t"));
mtm.appendChild(ovf);
anc = genAnc(arguments);
} else if (portletId == "p-tb") {
ovf = document.createElement("li");
var mtm = $("#sbm-toolbox ul").toArray()[0];
mtm.appendChild(ovf);
anc = genAnc(arguments);
} else if (portletId == "p-navigation") {
ovf = document.createElement("li");
var mtm = $("#sbm-navigation ul").toArray()[0];
mtm.appendChild(ovf);
anc = genAnc(arguments);
} else if (portletId == "p-personal") {
ovf = document.createElement("li");
var ulst = $("#ptools ul").toArray()[0];
ulst.appendChild(ovf);
anc = genAnc(arguments);
} else {
return save_mwutiladdPortletLink.apply(this, arguments);
};
ovf.appendChild(anc);
anc.appendChild(document.createTextNode(text));
return ovf;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
$(document).ready(truglassAria);
} else if (mw.config.get("skin") == "greystuff" && !mw.config.get("HarJIT-tabshim-loaded")) {
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var ovf; var anc; var ulst;
ovf = document.createElement("li");
if (portletId == "p-cactions") {
ulst = $("#p-actions ul").toArray()[0];
} else if (portletId == "p-tb") {
ulst = $("#p-tbx ul").toArray()[0];
} else if (portletId == "p-navigation") {
ulst = $("#p-Navigation ul").toArray()[0];
} else if (portletId == "p-personal") {
ulst = $("#p-personal ul").toArray()[0];
} else {
return save_mwutiladdPortletLink.apply(this, arguments);
};
ulst.appendChild(ovf);
anc = genAnc(arguments);
ovf.appendChild(anc);
anc.appendChild(document.createTextNode(text));
return ovf;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "cosmos" && !mw.config.get("HarJIT-tabshim-loaded")) {
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var ovf; var anc;
if (portletId == "p-cactions") {
// Not supported by default addPortletLink under Cosmos.
ovf = document.createElement("li");
ovf.setAttribute("class", "overflow");
var mtm = document.getElementById("cosmos-actionsList-list");
mtm.appendChild(ovf);
anc = genAnc(arguments);
} else if (portletId == "p-navigation") {
// Cosmos calls it p-Navigation not p-navigation for some reason.
return save_mwutiladdPortletLink.apply(this, ["p-Navigation", href, text]);
} else {
// Includes p-tb/p-personal, which default addPortletLink under Cosmos supports.
return save_mwutiladdPortletLink.apply(this, arguments);
};
ovf.appendChild(anc);
anc.appendChild(document.createTextNode(text));
return ovf;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "onyx" && !mw.config.get("HarJIT-tabshim-loaded")) {
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var ovf; var anc;
if (portletId == "p-cactions" || portletId == "p-tb") {
ovf = document.createElement("li");
ovf.setAttribute("class", "overflow");
var mtm = document.getElementById("onyx-tools-list");
mtm.appendChild(ovf);
anc = genAnc(arguments);
} else if (portletId == "p-navigation") {
ovf = document.createElement("li");
var ulst = document.getElementById("onyx-navigation-list");
ulst.insertBefore(ovf, ulst.firstChild); // ulst is a backward stacking flexbox.
anc = genAnc(arguments);
} else if (portletId == "p-personal") {
ovf = document.createElement("li");
var ulst = document.getElementById("onyx-personalTools-list");
ulst.appendChild(ovf);
anc = genAnc(arguments);
} else {
return save_mwutiladdPortletLink.apply(this, arguments);
};
ovf.appendChild(anc);
anc.appendChild(document.createTextNode(text));
return ovf;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if ((mw.config.get("skin") == "plurple" || mw.config.get("skin") == "plurpledark") && !mw.config.get("HarJIT-tabshim-loaded")) {
// Annoyingly, none of them seem to have unique IDs (though several have the ID #mw-panel, which is not how IDs are supposed to work)
// Accordingly this will probably break on other L10Ns.
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
if (portletId == "p-cactions") {
var ulst = document.querySelector("#content header .views ul");
} else if (portletId == "p-personal") {
var ulst = document.querySelector("ul[aria-label=User]");
} else {
// Including p-tb and p-navigation
return save_mwutiladdPortletLink.apply(this, arguments);
};
var ovf = document.createElement("li");
ulst.appendChild(ovf);
var anc = genAnc(arguments);
ovf.appendChild(anc);
anc.appendChild(document.createTextNode(text));
return ovf;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "monaco" && !mw.config.get("HarJIT-tabshim-loaded")) {
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var ovf;
if (portletId == "p-cactions") {
ovf = document.createElement("li");
var mtm = document.getElementById("page_controls");
mtm.appendChild(ovf);
} else if (portletId == "p-navigation") {
// Some versions have the menu items in an ul (DoomWiki), some as straight divs (ShoutWiki)
var mtm = $("#navigation ul").toArray()[0] || $("#navigation").toArray()[0];
ovf = document.createElement((mtm.nodeName.toLowerCase() == "ul")?("li"):("div"));
mtm.appendChild(ovf);
ovf.setAttribute("class", "menu-item");
} else if (portletId == "p-tb") {
ovf = document.createElement("li");
var uls = $("#link_box ul").toArray();
var mul = uls[0];
while (uls.length - 1) {
uls.splice(0, 1);
if ($(mul).children().length > $(uls[0]).children().length) {
mul = uls[0];
};
};
mul.appendChild(ovf);
} else if (portletId == "p-personal") {
ovf = document.createElement("li");
var ubar = document.getElementById("userData");
if (document.getElementById("headerButtonUser") !== null) {
ubar.insertBefore(ovf, document.getElementById("headerButtonUser").parentNode);
} else {
ubar.appendChild(ovf);
};
} else {
return save_mwutiladdPortletLink.apply(this, arguments);
};
var anc = genAnc(arguments);
ovf.appendChild(anc);
anc.appendChild(document.createTextNode(text));
return ovf;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if ((mw.config.get("skin") == "hydra" || mw.config.get("skin") == "hydradark") && !mw.config.get("HarJIT-tabshim-loaded")) {
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
if (portletId == "p-personal") {
var ovf = document.createElement("li");
var mtm = $("#netbar .user .dropdown").toArray()[0];
mtm.appendChild(ovf);
var anc = genAnc(arguments);
ovf.appendChild(anc);
anc.appendChild(document.createTextNode(text));
return ovf;
} else {
return save_mwutiladdPortletLink.apply(this, arguments);
};
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "exvius" && !mw.config.get("HarJIT-tabshim-loaded")) {
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var ovf = document.createElement("li");
if (portletId == "p-cactions") {
var mtm = $("#header-tools .sub-menu").toArray()[0];
mtm.insertBefore(ovf, $("#header-tools .sub-menu .label").toArray()[1]);
} else if (portletId == "p-navigation") {
var mtm = $("#menu").toArray()[0];
mtm.appendChild(ovf);
} else if (portletId == "p-tb") {
var mtm = $("#header-tools .sub-menu").toArray()[0];
mtm.appendChild(ovf);
} else if (portletId == "p-personal") {
var mtm = $("#netbar .user .dropdown").toArray()[0];
mtm.appendChild(ovf);
} else {
return save_mwutiladdPortletLink.apply(this, arguments);
};
var anc = genAnc(arguments);
ovf.appendChild(anc);
anc.appendChild(document.createTextNode(text));
return ovf;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "nimbus" && !mw.config.get("HarJIT-tabshim-loaded")) {
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var spa; var anc;
if (typeof arguments[3] != "undefined" && arguments[3] == "utcdate") {
return save_mwutiladdPortletLink.apply(this, arguments); // Sorry...
} else if (portletId == "p-navigation") {
var mtm = document.getElementById("menu");
var last_anc = $(mtm).children().toArray(); // Skipping text nodes.
last_anc = last_anc[last_anc.length-1];
last_anc.setAttribute("class",
last_anc.getAttribute("class").split("border-fix").join(""));
ovf = document.createElement("div");
mtm.appendChild(ovf);
ovf.setAttribute("class", "menu-item border-fix");
// Nimbus hardcodes mouseover colour in callbacks, might be changed by site: just don't bother.
// This differs from Monaco, which does it robustly using a :hover CSS selector.
spa = anc = genAnc(arguments);
ovf.appendChild(anc);
} else if (portletId == "p-cactions") {
// Some installations of Nimbus (Shoutwiki) seem to have the article-more-container (akin to Vector) while
// others (Halopedia) do not (akin to Monobook)
var cnt = document.getElementById("article-more-container") || document.getElementById("article-tabs");
var last_anc = $(cnt).children().toArray(); // Skipping text nodes.
var cleared = null;
if (last_anc[last_anc.length-1].nodeName.toLowerCase() == "div") {
cleared = last_anc[last_anc.length-1];
cnt.removeChild(cleared);
last_anc = last_anc.slice(0, -1);
}
last_anc = last_anc[last_anc.length-1];
last_anc.setAttribute("class",
last_anc.getAttribute("class").split("border-fix").join(""));
anc = genAnc(arguments);
anc.setAttribute("class", "border-fix tab-off");
cnt.appendChild(anc);
if (cleared) {
cnt.appendChild(cleared);
}
if (document.getElementById("article-more-container")) {
spa = anc;
} else {
spa = document.createElement("span");
anc.appendChild(spa);
}
} else if (portletId == "p-tb") {
var cnt = document.getElementById("other-links");
var chi = $(cnt).children().toArray(); // Skipping text nodes.
anc = genAnc(arguments);
cnt.appendChild(anc);
var clr;
if (chi[chi.length-3].getAttribute("class") == "cleared") {
// i.e. ends in a sandwich of one
clr = chi[chi.length-1]; // move the last one forward
} else {
clr = document.createElement("div");
clr.setAttribute("class", "cleared");
};
cnt.appendChild(clr);
spa = anc;
} else if (portletId == "p-personal") {
var cnt = document.getElementById("wiki-login");
anc = genAnc(arguments);
anc.setAttribute("class", "mw-skin-nimbus-button positive-button");
cnt.insertBefore(anc, $("#wiki-login .negative-button").toArray()[0]);
spa = document.createElement("span");
anc.appendChild(spa);
} else {
return save_mwutiladdPortletLink.apply(this, arguments);
};
spa.appendChild(document.createTextNode(text));
return anc;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if ((mw.config.get("skin") == "carbon" ||
mw.config.get("skin") == "carbongreen") && !mw.config.get("HarJIT-tabshim-loaded")) {
// Carbon (at least on ftbwiki.org) actually has a copy of mw.util.addPortletLink in place already,
// but not one ported to work with the Carbon skin itself. We simply need to patch it.
// I could do this just by patching the DOM, but that would entail overwriting existing IDs
// which is probably not a good idea.
document.getElementById("navigation").parentNode.setAttribute("id", "p-navigation");
document.getElementById("toolbox").parentNode.setAttribute("id", "p-tb");
var usermenuid = document.getElementById("user_link").parentNode.getAttribute("id");
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var newargs = Array.from(arguments).slice();
if (portletId == "p-personal") {
newargs[0] = usermenuid;
} else if (portletId == "p-cactions") {
newargs[0] = "admin_bar";
}
return save_mwutiladdPortletLink.apply(this, newargs);
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "strappingads3" && !mw.config.get("HarJIT-tabshim-loaded")) {
// Similarly with strappingads3 (wiki.aidancbrady.com)
var usermenuid = Array.from(document.querySelectorAll("#searchform+ul li.dropdown")).pop().getAttribute("id");
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var newargs = Array.from(arguments).slice();
if (portletId == "p-cactions") {
newargs[0] = "p-namespaces";
} else if (portletId == "p-tb") {
newargs[0] = "p-toolbox";
} else if (portletId == "p-navigation") {
newargs[0] = "page-header";
} else if (portletId == "p-personal") {
newargs[0] = usermenuid;
}
return save_mwutiladdPortletLink.apply(this, newargs);
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "chameleon" && !mw.config.get("HarJIT-tabshim-loaded")) {
// Similar approach to the other FTBWiki.org ones (Carbon, CarbonGreen).
document.getElementById("p-navigation").parentNode.setAttribute("id", "p-navigation-outer"); // See below
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var newargs = Array.from(arguments).slice();
if (portletId == "p-cactions") {
newargs[0] = "p-views";
} else if (portletId == "p-navigation") {
// Because the #p-navigation ID is on the UL itself, the existing addPortletLink implementation
// doesn't find an UL amongst its immediate descendents and appends one itself.
newargs[0] = "p-navigation-outer";
}
return save_mwutiladdPortletLink.apply(this, newargs);
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "minerva" && !mw.config.get("HarJIT-tabshim-loaded")) {
// i.e. when running with ?useskin=minerva and with the advanced mode enabled.
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var newargs = Array.from(arguments).slice();
if (portletId == "p-cactions") {
newargs[0] = "p-tb";
}
var myli = save_mwutiladdPortletLink.apply(this, newargs);
if (portletId != "p-navigation" && portletId != "p-interaction") {
myli.setAttribute("class", "toggle-list-item");
myli.firstChild.setAttribute("class", "toggle-list-item__label");
} else {
// Could alternatively just set toggle-list-item__label, but trying to match existing.
myli.firstChild.appendChild(document.createElement("span"));
myli.firstChild.lastChild.appendChild(myli.firstChild.firstChild);
}
return myli;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "aether" && !mw.config.get("HarJIT-tabshim-loaded")) {
// A skin used on KDE Community wiki. Misses out the IDs on several portlets without apporent reason.
// Also, puts the IDs on headings, not bodies.
document.querySelector(".menu-box:nth-of-type(2)").firstElementChild.setAttribute("id", "p-cactions");
document.querySelector(".menu-box:last-of-type").firstElementChild.setAttribute("id", "p-personal");
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var newargs = Array.from(arguments).slice();
if (document.getElementById(portletId)) {
document.getElementById(portletId).nextElementSibling.setAttribute("id", "PORTLET-BODY-OF-" + portletId);
newargs[0] = "PORTLET-BODY-OF-" + portletId;
}
return save_mwutiladdPortletLink.apply(this, newargs);
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "nostalgia" && !mw.config.get("HarJIT-tabshim-loaded")) {
// Has the basic addPortletLink but it's completely incompatible with the Nostalgia skin.
// It doesn't even use the same concept of operating as Monobook (not HTML lists but pipe-separated,
// several familiar portlets' functions and/or content duplicated in several places...)
// Caveat: sometimes has to add two links and can only return one (of course).
var toolbar_insert = $("a[rel=archives]")[0].nextSibling;
var toolbox_insert = $("#footer br")[0];
var toolbox_insert_for_toolbar = $("a[rel=archives]")[1].nextSibling;
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var anc;
if (portletId == "p-cactions") {
anc = genAnc(arguments);
anc.appendChild(document.createTextNode(text));
toolbox_insert_for_toolbar.parentNode.insertBefore(document.createTextNode(" |\n"), toolbox_insert_for_toolbar);
toolbox_insert_for_toolbar.parentNode.insertBefore(anc, toolbox_insert_for_toolbar);
anc = genAnc(arguments); // Need a second copy of the node.
anc.appendChild(document.createTextNode(text));
toolbar_insert.parentNode.insertBefore(document.createTextNode(" |\n"), toolbar_insert);
toolbar_insert.parentNode.insertBefore(anc, toolbar_insert);
} else if (portletId == "p-navigation") {
var nav_insert = document.getElementById("searchform").previousSibling;
anc = genAnc(arguments);
anc.appendChild(document.createTextNode(text));
nav_insert.parentNode.insertBefore(document.createTextNode(" |\n"), nav_insert);
nav_insert.parentNode.insertBefore(anc, nav_insert);
nav_insert = $('a[title="Special:RecentChanges"]')[0].nextSibling;
anc = genAnc(arguments); // Need a second copy of the node.
anc.appendChild(document.createTextNode(text));
nav_insert.parentNode.insertBefore(document.createTextNode(" |\n"), nav_insert);
nav_insert.parentNode.insertBefore(anc, nav_insert);
} else if (portletId == "p-tb") {
anc = genAnc(arguments);
anc.appendChild(document.createTextNode(text));
toolbox_insert.parentNode.insertBefore(document.createTextNode(" |\n"), toolbox_insert);
toolbox_insert.parentNode.insertBefore(anc, toolbox_insert);
} else if (portletId == "p-personal") {
var user_insert = document.getElementById("specialpages").previousSibling;
anc = genAnc(arguments);
anc.appendChild(document.createTextNode(text));
user_insert.parentNode.insertBefore(document.createTextNode(" |\n"), user_insert);
user_insert.parentNode.insertBefore(anc, user_insert);
} else {
return save_mwutiladdPortletLink.apply(this, arguments);
};
return anc;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else if (mw.config.get("skin") == "standard" && !mw.config.get("HarJIT-tabshim-loaded")) {
// Not a dissimilar deal to Nostalgia, being the other pre-Monobook skin.
var toolbar_insert = $("a[rel=archives]")[0].nextSibling;
var toolbox_insert_for_toolbar = $("a[rel=archives]")[1].nextSibling;
var mynew_mwutiladdPortletLink = function (portletId, href, text) {
var anc;
if (portletId == "p-cactions") {
anc = genAnc(arguments);
anc.appendChild(document.createTextNode(text));
toolbox_insert_for_toolbar.parentNode.insertBefore(document.createTextNode(" |\n"), toolbox_insert_for_toolbar);
toolbox_insert_for_toolbar.parentNode.insertBefore(anc, toolbox_insert_for_toolbar);
anc = genAnc(arguments); // Need a second copy of the node.
anc.appendChild(document.createTextNode(text));
toolbar_insert.parentNode.insertBefore(document.createTextNode(" |\n"), toolbar_insert);
toolbar_insert.parentNode.insertBefore(anc, toolbar_insert);
} else if (portletId == "p-navigation") {
var nav_insert = $("#quickbar hr").toArray()[1];
anc = genAnc(arguments);
anc.appendChild(document.createTextNode(text));
nav_insert.parentNode.insertBefore(anc, nav_insert);
nav_insert.parentNode.insertBefore(document.createElement("br"), nav_insert);
} else if (portletId == "p-tb") {
var quickbar = document.getElementById("quickbar");
anc = genAnc(arguments);
anc.appendChild(document.createTextNode(text));
quickbar.appendChild(anc);
quickbar.appendChild(document.createElement("br"));
} else if (portletId == "p-personal") {
var user_insert = $("#topbar td[align=right] br").toArray();
user_insert = user_insert[user_insert.length - 1];
anc = genAnc(arguments);
anc.appendChild(document.createTextNode(text));
user_insert.parentNode.insertBefore(document.createTextNode(" |\n"), user_insert);
user_insert.parentNode.insertBefore(anc, user_insert);
} else {
return save_mwutiladdPortletLink.apply(this, arguments);
};
return anc;
};
window.addPortletLink = mw.util.addPortletLink = mynew_mwutiladdPortletLink;
mw.config.set("HarJIT-tabshim-loaded", 1);
} else {
// Make sure both are the same.
window.addPortletLink = mw.util.addPortletLink = save_mwutiladdPortletLink;
};
//////////////////////////////////////////////////////////////////////////////////////////////////////
// mw.notify, mw.util.jsMessage, jsMsg
if (typeof jsMsg == "undefined" && typeof mw.util.jsMessage != "undefined") {
window.jsMsg = mw.util.jsMessage;
};
if (((window.location.href+"").indexOf("wikia.org") >= 0 || (window.location.href+"").indexOf("fandom.com") >= 0) &&
typeof mw.notify == "undefined") {
if (mw.config.get("skin") == "oasis") {
// Default jsMsg uses a div obscured by the top banner in Oasis/Wikia (so message text is
// not visible) and does not match the banner messages used by the Wikia software:
// replace it with a rewrite that does.
//
// With reference to:
//
// The confirmation message inserted in Oasis once user preferences are saved.
// The EU cookies warning when logged out.
//
// Invocation aims to be compatible with jsMsg aka mw.util.jsMessage. API docs:
// <1> https://www.mediawiki.org/wiki/ResourceLoader/Modules?oldid=2399938#jsMessage
// <2> https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.util-method-jsMessage
//
// Return value aims at compatibility with that of mw.notify:
// <3> https://doc.wikimedia.org/mediawiki-core/master/js/#!/api/mw.Notification_
//
window.jsMsg = mw.util.jsMessage = function (text) {
var style = "";
if (typeof text == "undefined" || text === null || text == "") {
return; // Following <1>, but messages are user-dismissible so largely N/A.
};
if ((arguments.length > 1) && arguments[1] !== null) {
style = arguments[1]; // Optional argument, see <1>
};
var a = document.getElementsByClassName("banner-notifications-placeholder")[0];
var b = document.createElement('span');
//var c = document.getElementById('WikiHeader');
var d = document.createElement("div");
var e = document.createElement("div");
var lic = document.createElement("div");
var f = document.createElementNS("http://www.w3.org/2000/svg", "svg");
var g = document.createElementNS("http://www.w3.org/2000/svg", "text");
var r = {"pause": function(){}, "resume": function(){}}; // <3> but not auto-dismiss
d.setAttribute("class", "wds-banner-notification__container");
// Otherwise defaults to transparent, odd when scrolling.
mw.util.addCSS(".jsmsg-custom-banner-notification { "+
"background: white; "+
"border: 1px solid silver; "+
"border-top: 0; }");
if (style == "info") {
style = "notify"; // Same purpose, the latter is the one used.
};
if (["notify","confirm","warn","error"].indexOf(style) >= 0) {
// OLD: Oasis seems to use the class names "confirm", "warn" and "error" directly on
// div.banner-notification elements, rather than e.g. mw-js-message-warn.
// NOW: wds-(alert, warning, success, message)
style = {"notify": "message", "confirm": "success",
"warn": "warning", "error": "alert"}[style];
e.setAttribute("class", "wds-banner-notification wds-"+style); // Sets bg/border colour
} else if (style == "") {
e.setAttribute("class", "wds-banner-notification wds-message");
} else {
e.setAttribute("class", "wds-banner-notification jsmsg-custom-banner-notification"+
" mw-js-message-" + style);
};
d.appendChild(e);
lic.setAttribute("class", "wds-banner-notification__icon");
e.appendChild(lic);
f.setAttribute("width", "12");
f.setAttribute("height", "12");
f.setAttribute("viewBox", "0 0 12 12");
r.close = f.onclick = function () { d.parentNode.style.height = (parseInt(d.parentNode.style.height || "0px") - 48) + "px"; d.parentNode.removeChild(d); }; // <3>
g.style["font-size"] = "24px";
g.setAttribute("x", "0");
g.setAttribute("y", "12");
g.appendChild(document.createTextNode("×"));
f.appendChild(g);
b.setAttribute("class", "wds-banner-notification__text");
e.appendChild(b);
f.setAttribute("class", "wds-icon wds-icon-tiny wds-banner-notification__close");
e.appendChild(f);
// Following <2> in the variety of object types accepted.
if (typeof text == "string") {
text = $.parseHTML(text);
};
$(b).append(text);
a.append(d); // insertBefore(d, c);
a.style.height = (parseInt(a.style.height || "0px") + 48) + "px";
return r;
};
};
// Invocations to mw.notify can be redirected to jsMsg without loss
// of basic functionality:
mw.notify = function (a) {
if (arguments.length-1 && typeof arguments[1].title != "undefined") {
a = "<b>" + arguments[1].title + "</b><br />" + a;
};
var r;
if (arguments.length-1 && typeof arguments[1].type != "undefined") {
r = jsMsg(a, arguments[1].type);
} else {
r = jsMsg(a);
};
if (r && typeof r.close == "undefined") {
r = {"close": function(){ jsMsg(""); }, "pause": function(){},
"resume": function(){} };
};
return r;
};
//
// Make mw.loader.using ignore dependency on mediawiki.notify:
var save_mwloaderusing = mw.loader.using;
var my_mwloaderusing = function (modules) {
var i; for (i = 0; i < modules.length; i += 1){
if (modules[i] == "mediawiki.notify") {
modules.splice(i, 1);
i -= 1;
};
};
return save_mwloaderusing.apply(this, arguments);
};
mw.loader.using = my_mwloaderusing;
} else if (mw.notify && typeof jsMsg == "undefined") {
// Inverse case: compatibility on wiki sites without legacy Wikibits.
window.jsMsg = function (s) { return mw.notify(s); };
};
}()){};
// End: [[m:User:HarJIT/portletnotifyshim.js]]