123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701 |
- /**
- * 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);
- }
|