123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302 |
- /**
- * 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: [],
- PlaceQuote: function() {
- const div = document.getElementById("footer-quote");
- let quote = {
- text: "Create a quotes.js file at static/quotes.js to add your quote to the footer.",
- source: ""
- };
- if (div) {
- if (this.all_quotes.length) {
- 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);
- }
|