/** * The globally-accessible Bumble Object * * Here I can store any and all utilities without taking up space in the * gloabl namespace. */ var Bumble = {}; /** * The info panel * * The info panel is a utility that allows me to add information to a page * in such a way that it can easily be closed when the user is done reading * it. * * This aims to improve the SEO of pages by adding as much descriptive * text as I want, without harming the usability of the page. This takes into * consideration that most of my pages are, currently, JS games on canvasses. * * @param {HTMLElement} panel - An HTML element with the .infopanel class */ Bumble.InfoPanel = function(panel){ this.panel = panel; this.head = undefined; this.body = undefined; this.title = undefined this.closer = undefined; this.icons = { close: "uil-times-circle", open: "uil-info-circle" } this.isClosed = false; /** * Initialzize the info panel */ this.init = function(){ if(!this.panel){ throw new Error("Panel not found."); } this.head = this.panel.querySelector('.infopanel-head'); this.body = this.panel.querySelector('.infopanel-body'); this.title = this.head.querySelector('.infopanel-title'); this.closer = this.head.querySelector('.infopanel-closer'); this.isClosed = this.panel.classList.contains('closed'); this.closer.addEventListener("click", ()=>{ this.toggleVisibility(); }); this.toggleCloseButtonIcon(); } /** * Close the info panel */ this.close = function() { this.panel.classList.add("closed"); this.isClosed = true; } /** * Open the info panel */ this.open = function() { this.panel.classList.remove("closed") this.isClosed = false; } /** * Toggle the info panel's visibility */ this.toggleVisibility = function() { if(this.isClosed) { this.open(); } else { this.close(); } this.toggleCloseButtonIcon(); } /** * Toggle the icon of the info panel's open/close button */ this.toggleCloseButtonIcon = function() { if(this.isClosed) { this.closer.classList.remove(this.icons.close); this.closer.classList.add(this.icons.open); } else { this.closer.classList.remove(this.icons.open); this.closer.classList.add(this.icons.close); } } this.init(); } /** * A classic modal * * @param {string} DOMID - An option string of the DOM ID for premade modal */ Bumble.Modal = function(DOMID) { this.overlay = undefined; this.modal = { base: undefined, header: undefined, title: undefined, closer: undefined, body: undefined }; this.isShown = false; this.init = function(DOMID) { // Build the overlay this.overlay = document.createElement("div"); this.overlay.classList.add("modal-overlay", "hidden"); // Initialize a predefined modal if(DOMID) { const elem = document.getElementById(DOMID); if(!elem){ console.warn("No element found with ID: ", DOMID); console.warn("Creating modal"); } else { this.modal.pane = elem; this.modal.header = elem.querySelector(".modal-header"); this.modal.title = elem.querySelector(".modal-title"); this.modal.closer = elem.querySelector(".uil-times-circle"); this.modal.body = elem.querySelector(".modal-body"); } } // Build the modal from scratch if(!this.modal.pane) { this.modal.pane = document.createElement("div"); this.modal.pane.classList.add("modal"); this.modal.header = document.createElement("div"); this.modal.header.classList.add("modal-header"); this.modal.title = document.createElement("div"); this.modal.title.classList.add("modal-title"); const closerContainer = document.createElement("div"); closerContainer.classList.add("modal-closer", "text-right"); this.modal.closer = document.createElement("i"); this.modal.closer.classList.add("uil", "uil-times-circle"); closerContainer.appendChild(this.modal.closer); this.modal.header.append(this.modal.title, closerContainer); this.modal.body = document.createElement("div"); this.modal.body.classList.add("modal-body"); this.modal.pane.append(this.modal.header, this.modal.body); } // Add event listener to closer button this.modal.closer.addEventListener("click", this.hide.bind(this)); // Add modal pane to the overlay this.overlay.appendChild(this.modal.pane); // Add overlay to body document.body.appendChild(this.overlay); return; } this.SetTitle = function(title) { this.modal.title.innerText = title; } this.SetBody = function(bodyHTML) { this.modal.body.innerHTML = bodyHTML; } this.show = function() { this.isShown = true; this._toggleVisibility(); } this.hide = function() { this.isShown = false; this._toggleVisibility(); } this._toggleVisibility = function() { if(this.isShown) { this.overlay.classList.remove("hidden"); } else { this.overlay.classList.add("hidden"); } } this.init(DOMID); } /** * Store GET Parameters * * A convenient place to store and access GET parameters sent to the page. */ Bumble._GET = { /** * Loads the GET parameters into this object */ __init: function() { const params = (new URL(document.location)).searchParams.entries(); for(const entry of params) { if(entry[0] == "__init"){ continue; } this[entry[0]] = !isNaN(entry[1]) ? Number(entry[1]) : entry[1]; } } } Bumble.XFN = { me: "uil-cell", friend: "uil-user-check", colleague: "uil-books", _buildIcon: function(iconClass) { const icon = document.createElement("i"); icon.classList.add("uil", iconClass); return icon; }, init: function() { const links = document.querySelectorAll("a[rel]"); for(const link of links) { // Ignore links that only contain images if (link.childNodes.length == 1 && link.lastChild instanceof HTMLImageElement) { continue; } const rels = link.rel.split(' '); let rel = null; if(rels.indexOf("me") >= 0) { rel = this.me; } else if(rels.indexOf("friend") >= 0) { rel = this.friend; } else if(rels.indexOf("colleague") >= 0) { rel = this.colleague; } if(rel) { link.insertAdjacentElement("afterbegin", this._buildIcon(rel)); } } }, } /** * Quotes that either have a lot of meaning to me, or I just really enjoy */ Bumble.FooterQuotes = { all_quotes: [ { "text":"We can't rewind now; we've gone too far", "source":"The Limousines - Internet Killed The Video Star" }, { "text":"There is no justice or no peace, there's only forgiveness", "source":"John Reuben - There's only Forgiveness" }, { "text":"Love is like a circle; there's no easy way to end", "source":"Oliver Tree - Cowboys Don't Cry" }, { "text":"No crime is as bad as meaninglessness", "source":"Futhermore - Letter To Myself" }, { "text":"Independence was the goal, now you miss home sick", "source":"Futhermore - Letter To Myself" }, { "text":"Apathy's a tragedy, and boredom is a crime", "source":"Bo Burnham - Welcome To The Internet" }, { "text":"All I ever wanted was a little bit of everything all of the time", "source":"Bo Burnham - Welcome To The Internet" }, { "text":"The taste of blood; It's murder; This is your fault; You chose this path.", "source":"Mayhem - It's Murder" }, { "text":"So it goes.", "source":"Kurt Vonnegaut - Slaughter-house Five" }, { "text":"He has always pressed it, and he always will. We always let him and we always will let him. The moment is structured that way.", "source":"Kurt Vonnegaut - Slaughter-house Five" }, { "text":"This isn't a man. It's a broken kite.", "source":"Kurt Vonnegaut - Slaughter-house Five" }, { "text":"Why you? Why us for that matter? Why Anything? Because the moment simply is.", "source":"Kurt Vonnegaut - Slaughter-house Five" }, { "text":"Poo-tee-tweet?", "source":"Kurt Vonnegaut - Slaughter-house Five" }, { "text":"Yeah there's nothing left to ruin, yeah we finally got free / How's that for manifesting our destiny", "source":"Sylvan Esso - PARAD(w/m)E" }, { "text":"Where you been? I wonder / We've been waitin so long around here for days, days, days", "source":"Mr. Gnome - Pixie Dust" }, { "text":"We will laugh at the fact that we ever resisted this blissful togetherness", "source":"Rachel Kann - I Know This" }, { "text":"Who mistook the steak for chicken?", "source":"Moldy Peaches - Steak For Chicken" }, { "text":"We're not those kids, sitting on the couch", "source":"Moldy Peaches - Steak For Chicken" }, { "text":"Death will give us back to God / Just like the setting sun is returned to lonesome ocean", "source":"Bright Eyes - At The Bottom Of Everything" }, { "text":"I'm happy just because / I found out I am really no one", "source":"Bright Eyes - At The Bottom Of Everything" }, { "text":"There'll always be a few things, maybe several things / That you're gonna find really difficult to forgive", "source":"The Mountain Goates - Up The Wolves" }, { "text":"It's gonna take you people years to recover from all of the damage", "source":"The Mountain Goates - Up The Wolves" }, { "text":"Your sleepy anarchy... Wake it Up! Wake it up!", "source":"TeddyLoid Ft. Debra Zeer - D City Rock" }, { "text":"I just miss how it felt standing next to you / Wearing matching dresses before the world was big", "source":"Girlpool - Before The World Was Big" }, { "text":"I have to be fucking with something I love if I'm burning both ends of my candle stick", "source":"Ceschi, Factor Chandelier & Sammus - Middle Earth" }, { "text":"Why you tweetin' at the top of your lungs?", "source":"Lil Darkie - COMFORT IN DISCOMFORT" }, { "text":"It's almost over / It's just begun", "source":"Bo Burnham - All Eyes On Me" }, { "text":"You say the whole world's ending, honey, it already did", "source":"Bo Burnham - All Eyes On Me" }, { "text":"You're drowning in the grief of Jupiter's waters", "source":"Terrance Zdunich - Grief (Alternate Version)" }, { "text":"I'd rather nap than wonder, restlessly / Will you ever be impressed by me?", "source":"Crying - ES" }, { "text":"How did you become this way?", "source":"Crying - ES" }, { "text":"I'll embrace dreams again when I can breathe again / And at that point I won't be needing them", "source":"John Reuben - Chapter 1" }, { "text":"The revolution didn't leave you, it never came", "source":"John Reuben - Chapter 1" }, { "text":"When real life is reality TV, no wonder our youth don't believe in anything", "source":"John Reuben - Chapter 1" }, { "text":"There are no heroes, just those of us with high hopes", "source":"John Reuben - Chapter 1" }, { "text":"Puff the magic Jesus floats around the universe; The United States is his favorite place on the whole entire Earth", "source":"John Reuben - What About Them?" }, { "text":"History is best forgotten and even better rewritten / And since there's no forgetting, let's remember it different", "source":"John Reuben - What About Them?" }, { "text":"Four walls with no windows doesn't mean you're it / Four walls with no windows doesn't mean they don't exist", "source":"John Reuben - What About Them?" }, { "text":"Ignore the crying outside the door / Sure, you'll pray for their burdens, but you don't want to make it yours", "source":"John Reuben - What About Them?" }, { "text":"The more you have, the less you care / The less you care, the more you become unaware", "source":"John Reuben - What About Them?" }, { "text":"Try to sell it to God, and see if he buys your sales pitch", "source":"John Reuben - Sales Pitch" }, { "text":"Everyone's got an agenda. Can you tell me what's yours?", "source":"John Reuben - Sales Pitch" }, { "text":"Job well done, Religion. Look what you've created.", "source":"John Reuben - Sales Pitch" }, { "text":"God bless us as we sweep this mess under the rug", "source":"John Reuben - What About Them?" }, { "text":"It's not the way I'm meant to be / It's just the way the operation made me", "source":"The Dresden Dolls - Girl Anachronism" }, { "text":"Behold the world's worst accident / I am the girl anachronism", "source":"The Dresden Dolls - Girl Anachronism" }, { "text":"I don't necessarily believe there is a cure for this, so I might join your century as a doubtful guest", "source":"The Dresden Dolls - Girl Anachronism" }, { "text":"Do you love me? Yes, no, maybe. I'll be seeing Hades soon", "source":"JACK THE STRIPPER Ft. Byrds - PHANTASM" }, { "text":"Define \"terrorist\"", "source":"Me - On the subject of governments trying to stop \"terrorists\"" }, { "text":"What goal would justify the suffering of your life", "source":"Jordan Peterson" }, { "text":"The goal is to be wrong in interesting ways", "source":"Abigail Thorn" }, { "text":"God help the outcast with her witchcraft / Some day I'm gonna go home", "source":"Sherclop Pones - Pinkie's Brew" }, { "text":"When I wrote this code, only God and I knew how it worked. Now, only God knows it!", "source":"Unknown Developer" }, { "text":"It's okay to be different things in different places.", "source":"@alis@fandom.ink - https://fandom.ink/@alis/109545392718134930" }, { "text":"You're nobody till somebody wants you dead", "source":"Saint Motel - You're Nobody Till Somebody Wants You Dead" }, { "text":"You ask a silly question, you get a silly answer.", "source":"Tom Lehrer - New Math" }, { "text":"But I don't want to go to sleep; in all my dreams I drown.", "source":"The Devil's Carnival - In All My Dreams I Drown" }, { "text":"We are the life, we are the light / We are the envy of the Gods above", "source":"The Orion Experience - The Cult of Dionysus" }, { "text":"Let's get mischievous, and polyamorous", "source":"The Orion Experience - The Cult of Dionysus" }, { "text":"Don't give up yet, no don't ever quit / There's always a chance for a critical hit.", "source":"Ghost Mice - Critical Hit" }, { "text":"Shut your mouth / Listen up when I talk / I'm a spoiled little brat and I get what I want", "source":"Underscores - Spoiled Little Brat" }, { "text":"In my life, I hope I lie, and tell everyone you were a good wife", "source":"The Mountain Goats - No Children" }, { "text":"I hope you Die / I hope we both die", "source":"The Mountain Goats - No Children" }, { "text":"I hope it stays dark forever / I hope the worst the isn't over", "source":"The Mountain Goats - No Children" }, { "text":"I hope when you think of me years down the line, you can't think of one good thing to say", "source":"The Mountain Goats - No Children" }, { "text":"And I'd hope that if I found the strength to walk out, you'd stay the hell out of my way", "source":"The Mountain Goats - No Children" }, { "text":"I am Drowning / There is no sign of land / You are coming down with me / Hand in unlovable hand", "source":"The Mountain Goats - No Children" }, { "text":"If I had a dime for every man that's stolen mine, I'd be right back where I started", "source":"Larry and His Flask - Breaking Even" }, { "text":"I can't decide whether you should live or die. Oh you'll probably go to Heaven. Please don't hang your head and cry.", "source":"Scissor Sisters - I Can't Decide" }, { "text":"I've got to hand it to you / You played by all the same rules. It takes the truth to fool me, and now you've made me angry.", "source":"Scissor Sisters - I Can't Decide" }, { "text":"A bit of mustard adds reality", "source":"An advertisement for a rubber hotdog prank" }, { "text":"You're closer to a jail cell than you'll ever be to God", "source":"CALYPSO - The Exorcist" }, { "text":"Love thy neighbor, right? Or is it only if they're rich, able-bodied, cis, hetero and white?", "source":"CALYPSO - The Exorcist" }, { "text":"Plenty of time until it's gone. It's alright until it's not.", "source":"Worthikids - Spinning Wheel" }, { "text":"How many times have I looped this song? When did my hair get so long?", "source":"Worthikids - Spinning Wheel" }, { "text":"And the future never comes. What comes is always here, now.", "source":"Osho, Indian Philosopher" }, { "text":"It is a series of nows. One now, another now, but you are always living in the now.", "source":"Osho, Indian Philosopher" }, { "text":"I'm a person among other people, and I deserve at least as much respect as a person among other people", "source":"Jordan Peterson" }, { "text":"I didn't know the Russians had tea!", "source":"A customer I overheard commenting on my bakery's Russian Tea Biscuits" }, { "text":"What is youth, if not a time to be forgiven for one's transgressions?", "source":"Gale from Baldur's Gate 3" }, { "text":"Something's wrong when you regret things that haven't happened yet", "source":"The Submarines - 1940" }, { "text":"Why worry about yesterday's fuckups when you have tomorrow's fuckups to look forward to?", "source":"@masood_boomgaard@tiktok.com" }, { "text":"You will be okay. You have no other option.", "source":"/u/kristencolby on Reddit" }, { "text":"waga baga bobo", "source":"The jailer has decided to execute you" }, { "text":"I don't know what I'm gonna do / I can't keep anything at all from slipping through my raccoon claws", "source":"Penelope Scott - Soap" }, { "text":"I don't know what I'm doing, but I am okay with losing", "source":"That Handsome Devil - F2F" }, { "text":"I don't know what I'm doing, but I'm not afraid of losing", "source":"That Handsome Devil - F2F" }, { "text":"You deserve to get to know the person you're trying your damnedest to let go", "source":"36 Questions - Hear Me Out" }, { "text":"Only you can be the one to say you're through, and walk away", "source":"36 Questions - Answer 36" }, { "text":"I deserve to let you go, and build a better version on my own, somehow", "source":"36 Questions - Answer 36" }, { "text":"It's strange to imagine my everyday without you", "source":"36 Questions - Answer 36" }, { "text":"What's true for you doesn't have to be true forever", "source":"36 Questions - The Truth" }, { "text":"The truth is that the truth doesn't exist in black and white, and some times two sides can both be right", "source":"36 Questions - The Truth" }, { "text":"I know for sure I don't wanna be a rockstar if it makes me what you are", "source":"Woz - Child Support" }, { "text":"Next time your song is playing at the bar I swear I'll go hom. At least I know you won't be there.", "source":"Woz - Child Support" }, { "text":"Daddy's little girl paints the world with her magic wand", "source":"Jesse Spencer - Molly Smiles" }, { "text":"I'm still fixing who you make me / But one day I'll forget it even happened", "source":"Addison Grace - Manic Pixie Dream Girl" }, { "text":"Pity me, I'm almost a human being", "source":"Aurelio Voltaire - Almost Human" }, { "text":"Look at me, I'm almost a human being", "source":"Aurelio Voltaire - Almost Human" }, { "text":"I'm just like you, made by He, despised by They, I'm almost me", "source":"Aurelio Voltaire - Almost Human" }, { "text":"I know money's for managers, but goddamit, art is for amateurs", "source":"Jam Mechanics, Bug Hunter, The Narcissist Cookbook - Art is for Amateurs" }, ], PlaceQuote: function() { const div = document.getElementById("footer-quote"); if (div) { quote = this.all_quotes[Math.floor(Math.random() * this.all_quotes.length)]; div.innerText = quote.text; console.log(`Quote source: ${quote.source}`); } }, /** * Add a quote to the list of possible quotes to display in the footer * * @param {string} quote The quote to display in the footer * @param {string} source The source of the quote that will be logged in the browser's console */ AddQuote: function(quote, source) { this.all_quotes.push({ text: quote, source: source, }); } } function page_init() { /* Initialize info panels */ const panels = document.querySelectorAll('.infopanel'); for(const panel of panels) { panel._infoPanel = new Bumble.InfoPanel(panel); } Bumble._GET.__init(); Bumble.XFN.init(); Bumble.FooterQuotes.PlaceQuote(); } if(document.readyState != 'loading') { page_init(); } else { document.addEventListener('DOMContentLoaded', page_init); }