User:Melecie/Scripts/queer-rainbows.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 code will be executed when previewing this page.
This user script seems to have a documentation page at User:Melecie/Scripts/queer-rainbows.
/***************************************************************************************************
* queer-rainbows.js by [[User:Melecie]]
* This fun userscript embeds a related queer gradient for the titles of queer-related pages! :3
***************************************************************************************************/
// init important variables
let queerRainbows_banner = "";
let queerRainbows_categories = mw.config.get("wgCategories");
let queerRainbows_namespace = mw.config.get("wgCanonicalNamespace");
let queerRainbows_title = mw.config.get("wgTitle");
let queerRainbows_skinUsed = mw.config.get("skin");
for (let i in queerRainbows_categories) {
queerRainbows_categories[i] = queerRainbows_categories[i].toLowerCase();
}
// dictionaries below
const queerRainbows_colorGradients = {
"rainbow": ["f9bbc0", "f9dbbb", "f9f1bb", "bbf9bb", "bbc7f9", "e1bbf9"],
"gay": ["95e0e2", "bbf7f9", "ffffff", "bbc7f9", "9598e2"],
"achillean": ["bbc7f9", "bbc7f9", "ffffff", "d0ead0", "ffffff", "bbc7f9", "bbc7f9"],
"lesbian": ["e2959e", "f9dbbb", "ffffff", "f9bbf3", "d495e2"],
"sapphic": ["f9bbf3", "f9bbf3", "ffffff", "e1a8ed", "ffffff", "f9bbf3", "f9bbf3"],
"bisexual": ["9598e2", "9598e2", "e1bbf9", "d495e2", "d495e2"],
"pansexual": ["f9bbd5", "f9bbd5", "f9bbd5", "faefbb", "faefbb", "faefbb", "bbcff9", "bbcff9", "bbcff9"],
"aromantic": ["bae8b4", "d7f9bb", "ffffff", "e6eae3", "d0d3cd"],
"asexual": ["d4c9d6", "e4d5e8", "ffffff", "e1bbf9"],
"aroace": ["e8ceb4", "f9f1bb", "ffffff", "bbcff9", "b8c4e0"],
"transgender": ["bbf7f9", "f9bbf1", "ffffff" ,"f9bbf1", "bbf7f9"],
"transfeminine": ["bbf7f9", "f7e3f4", "f7d4f2", "f9bbf1", "f7d4f2", "f7e3f4", "bbf7f9"],
"transmasculine": ["f9bbf1", "e6f6f7", "d6f8f9", "bbf7f9", "d6f8f9", "e6f6f7", "f9bbf1"],
"nonbinary": ["f9f1bb", "ffffff", "e1bbf9", "c2afc6"],
"genderqueer": ["e1bbf9", "ffffff", "bbf9bb"],
"genderfluid": ["f9bbf3", "ffffff", "e1bbf9", "b8b8d1", "9598e2"],
"agender": ["d0d3cd", "e6eae3", "ffffff", "d7f9bb", "ffffff", "e6eae3", "d0d3cd"],
"intersex": ["f9f1bb", "f9f1bb", "e1bbf9", "f9f1bb", "f9f1bb"],
"queer": ["f9bbf3", "c2afc6"],
};
const queerRainbows_articlesWithPredefinedBanners = {
"": ["man", "woman", "cisgender", "personal pronoun", "androgyny", "endosex"],
"rainbow": ["questioning (sexuality and gender)", "kinsey scale", "klein sexual orientation grid", "androphilia and gynephilia"],
"gay": [],
"achillean": [],
"lesbian": [],
"sapphic": ["sapphism"],
"bisexual": [],
"pansexual": [],
"aromantic": [],
"asexual": [],
"aroace": ["aro-ace"],
"transgender": ["hormone replacement therapy"],
"transfeminine": ["trans woman"],
"transmasculine": ["trans man"],
"nonbinary": [],
"intersex": [],
};
const queerRainbows_bannerRegexes = {
"rainbow_lastcheck": /lgbt|queer|homosexuality|same-sex sexuality|wiki loves pride/g, // will be checked last // lgbt also matches lgbtq of course, but is left as such to also catch anything still using just that
"rainbow": /^(?!male).*homosexuality$|same-sex sexuality/g, // first section also un-matches "female homosexuality"
"gay": /gay|male homosexuality/g,
"lesbian": /lesbian/g,
"sapphic": /sapphism|sappho/g, // sappho has not much to do with the sexuality other than through sappho herself, but come on i had to do it
"bisexual": /(bi|pluri)sexual|sexual fluidity/g,
"pansexual": /pansexual/g,
"aromantic": /aromantic/g,
"asexual": /^.*(demi|a)sexual(?! reproduction).*$/g,
"agender": /agender/g,
"transgender": /transgender|^(?!disputed).*gender identity.*$|gender transition/g,
"transmasculine": /masculinizing (hormone therapy|surgery)|transgender men/g,
"transfeminine": /feminizing (hormone therapy|surgery)|transgender women/g,
"nonbinary": /non-?binary|third gender|gender systems|gender[- ]neutral/g,
"genderfluid": /gender ?fluid/g,
"intersex": /intersex/g,
};
// does a regex scan of all categories in a page and returns true if detected
function queerRainbows_checkCategoriesForMatch(regex) {
for (let c of queerRainbows_categories) {
if (c.match(regex)) { return true; }
}
return false;
}
// removes a given item from an array and returns the new array
function queerRainbows_removeFromArray(arr, str) {
if (!arr.includes(str)) { return arr; }
arr.splice(arr.indexOf(str), 1);
return arr;
}
// run for articlespace
function queerRainbows_articlespace() {
// some articles get predefined banners.
// scan if this article is one of them!
for (let curr in queerRainbows_articlesWithPredefinedBanners) {
if (queerRainbows_articlesWithPredefinedBanners[curr].includes(queerRainbows_title.toLowerCase())) {
queerRainbows_banner = curr;
return;
}
}
// shunt for biographies
if ($(".biography").length > 0) {
// biographies
let bannerArray = [];
// each banner type gets a regex test, if it passes a regex test, the article gets can get that banner
for (let curr of ["intersex", "agender", "genderfluid", "nonbinary", "transfeminine", "transmasculine", "transgender", "aromantic", "asexual", "pansexual", "bisexual", "gay", "lesbian"]) {
if (queerRainbows_checkCategoriesForMatch(queerRainbows_bannerRegexes[curr])) {
bannerArray.push(curr);
}
}
if (bannerArray.length == 0) {
// try to match against rainbow_lastcheck if nothing has been matched yet
if (queerRainbows_checkCategoriesForMatch("rainbow_lastcheck")) { queerRainbows_banner = "rainbow"; }
} else {
// transfeminine + transgender --> just transfeminine
if (bannerArray.includes("transgender") && bannerArray.includes("transfeminine")) {
bannerArray = queerRainbows_removeFromArray(bannerArray, "transgender");
}
// transmasculine + transgender --> just transmasculine
if (bannerArray.includes("transgender") && bannerArray.includes("transmasculine")) {
bannerArray = queerRainbows_removeFromArray(bannerArray, "transgender");
}
console.log(bannerArray);
// aromantic + asexual --> replace both with aroace
if (bannerArray.includes("aromantic") && bannerArray.includes("asexual")) {
bannerArray = queerRainbows_removeFromArray(bannerArray, "aromantic");
bannerArray = queerRainbows_removeFromArray(bannerArray, "asexual");
bannerArray.push("aroace");
}
// select one of the available categories by random
idx = Math.floor(Math.random() * bannerArray.length);
queerRainbows_banner = bannerArray[idx];
}
} else {
// non-biographies
// each banner type gets a regex test, if it matches one of the articles, the article gets that banner immediately
for (let curr of ["sapphic", "intersex", "genderfluid", "nonbinary", "transfeminine", "transmasculine", "transgender", "aromantic", "asexual", "pansexual", "bisexual", "rainbow", "gay", "lesbian", "rainbow_lastcheck"]) {
if (queerRainbows_checkCategoriesForMatch(queerRainbows_bannerRegexes[curr])) {
if (curr == "rainbow_lastcheck") { queerRainbows_banner = "rainbow"; }
else { queerRainbows_banner = curr; }
return;
}
}
}
}
// run for userspace
function queerRainbows_userspace() {
let bannerArray = [];
// check for all their LGBTQ Wikipedians categories and add each one to the rotation
if (queerRainbows_categories.includes("gay wikipedians")) { bannerArray.push("gay"); }
if (queerRainbows_categories.includes("lesbian wikipedians")) { bannerArray.push("lesbian"); }
if (queerRainbows_categories.includes("bisexual wikipedians")) { bannerArray.push("bisexual"); }
if (queerRainbows_categories.includes("pansexual wikipedians")) { bannerArray.push("pansexual"); }
if (queerRainbows_categories.includes("non-binary wikipedians")) { bannerArray.push("nonbinary"); }
if (queerRainbows_categories.includes("agender wikipedians")) { bannerArray.push("agender"); }
if (queerRainbows_categories.includes("genderfluid wikipedians")) { bannerArray.push("genderfluid"); }
if (queerRainbows_categories.includes("intersex wikipedians")) { bannerArray.push("intersex"); }
if (queerRainbows_categories.includes("queer wikipedians")) { bannerArray.push("queer"); }
if (queerRainbows_categories.includes("aromantic wikipedians")) { bannerArray.push("aromantic"); }
if (queerRainbows_categories.includes("asexual wikipedians")) { bannerArray.push("asexual"); }
// prioritize transfem/transmasc banner over a general trans banner
if (queerRainbows_categories.includes("trans women wikipedians")) { bannerArray.push("transfeminine"); }
if (queerRainbows_categories.includes("trans men wikipedians")) { bannerArray.push("transmasculine"); }
if (queerRainbows_categories.includes("transgender wikipedians") && !bannerArray.includes("transfeminine" && !bannerArray.includes("transmasculine"))) {
bannerArray.push("transgender");
}
if (bannerArray.length == 0) {
// if they do not have one of the specific categories but have the LGBTQ Wikipedians one anyway, add a rainbow in
if (queerRainbows_categories.includes("lgbtq wikipedians")) { queerRainbows_banner = "rainbow"; }
} else {
// aromantic + asexual --> replace both with aroace
if (bannerArray.includes("aromantic") && bannerArray.includes("asexual")) {
bannerArray = queerRainbows_removeFromArray(bannerArray, "aromantic");
bannerArray = queerRainbows_removeFromArray(bannerArray, "asexual");
bannerArray.push("aroace");
}
// select one of the available categories by random
idx = Math.floor(Math.random() * bannerArray.length);
queerRainbows_banner = bannerArray[idx];
}
}
// run for categoryspace
function queerRainbows_categoryspace() {
// does the name of this category match one of these regexes below?
// the main way we try to check for the banner to apply to the page is through categories
// so this simply fits here
for (let curr of ["sapphic", "intersex", "genderfluid", "nonbinary", "transfeminine", "transmasculine", "transgender", "aromantic", "asexual", "pansexual", "bisexual", "rainbow", "gay", "lesbian", "rainbow_lastcheck"]) {
if (queerRainbows_title.toLowerCase().match(queerRainbows_bannerRegexes[curr])) {
if (curr == "rainbow_lastcheck") { queerRainbows_banner = "rainbow"; }
else { queerRainbows_banner = curr; }
return;
}
}
}
// paint the title/name with the applicable banner
function queerRainbows_painter() {
// end if no selected color gradient
if (queerRainbows_banner == "" || !Object.keys(queerRainbows_colorGradients).includes(queerRainbows_banner)) { return; }
// generate the code for the background css property
let selectedColorGradient = queerRainbows_colorGradients[queerRainbows_banner];
let backgroundCss = "linear-gradient(to right,";
for (let i = 0; i < selectedColorGradient.length; i++) {
backgroundCss += "#" + selectedColorGradient[i] + (i+1 < selectedColorGradient.length ? "," : "");
}
backgroundCss += ")";
// switch method of display based on the currently used skin
let pageTitleObj = {};
switch (queerRainbows_skinUsed) {
case "vector": // Vector Legacy
pageTitleObj = $(".firstHeading");
pageTitleObj.css({
"margin-bottom": "0px 0.2em",
"padding": "0em 0.8em",
"border-radius": "8px",
"border-bottom": "0px none #aaa",
"background": backgroundCss,
});
break;
case "vector-2022": // Vector 2022
pageTitleObj = $(".mw-body-header");
pageTitleObj.css({
"border-radius": "8px",
"background": backgroundCss,
});
let pageTitleContainerVector2022 = $(".firstHeading");
pageTitleContainerVector2022.css({
"padding": "0em 0.5em",
});
let pageHeaderVector2022 = $(".vector-sticky-header");
pageHeaderVector2022.css({
"background": backgroundCss,
});
break;
case "monobook": // Monobook / fallback
pageTitleObj = $(".firstHeading");
pageTitleObj.css({
"margin": "0.3em 0em 0em 0em",
"padding": "0.2em 0.5em",
"border-radius": "8px",
"border-bottom": "0px none #aaa",
"background": backgroundCss,
});
break;
case "minerva": // MinervaNeue
pageTitleObj = $(".firstHeading");
pageTitleObj.css({
"padding": "0em 0.5em",
"border-radius": "16px",
"background": backgroundCss,
});
break;
case "timeless": // Timeless
pageTitleObj = $(".firstHeading");
pageTitleObj.css({
"padding": "0.1em 0.5em 0.1em 0.5em",
"margin": "0.15em 0em 0.4em 0em",
"border-radius": "8px",
"background": backgroundCss,
"border-bottom": "0px none #aaa",
});
break;
case "cologneblue": // Cologne Blue
pageTitleObj = $("#firstHeading");
pageTitleObj.css({
"padding": "0.1em 0.5em 0.1em 0.5em",
"margin": "0.3em 0em 0em 0em",
"border-radius": "8px",
"border-bottom": "0px none #aaa",
"background": backgroundCss,
});
break;
case "modern": // Modern
pageTitleObj = $("#mw_header");
pageTitleObj.css({
"background": backgroundCss,
"color": "black",
});
let pageHeaderModern = $(".firstHeading");
pageHeaderModern.css({
"border-bottom": "0px none #000",
});
break;
case "apioutput": // APIOutput
pageTitleObj = $("#firstHeading");
pageTitleObj.css({
"padding": "0.17em 0.5em 0.17em 0.5em",
"margin": "0.53em 0em 0.6em 0em",
"border-radius": "8px",
"border-bottom": "0px none #aaa",
"background": backgroundCss,
});
break;
default: // fallback
console.log("[[User:Melecie/queer_rainbows.js]] - Skin not officially supported - running fallback~");
pageTitleObj = $(".firstHeading");
pageTitleObj.css({
"padding": "0em 0.5em",
"border-radius": "8px",
"background": backgroundCss,
});
break;
}
}
// main function
function queerRainbows_main() {
switch(queerRainbows_namespace) {
case "": queerRainbows_articlespace(); break;
case "Project": queerRainbows_articlespace(); break;
case "User": queerRainbows_userspace(); break;
case "Category": queerRainbows_categoryspace(); break;
}
queerRainbows_painter();
}
queerRainbows_main();