Jump to content

User:Melecie/Scripts/queer-rainbows.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/***************************************************************************************************
* 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();