Skip to content
Snippets Groups Projects
rulesAssistantOptions.js 115 KiB
Newer Older
brickode's avatar
brickode committed
/* eslint-disable camelcase */
brickode's avatar
brickode committed
/* eslint-disable no-unused-vars */
vas's avatar
vas committed
// rewrite of the rules assistant options page in javascript
// uses an object-oriented widget pattern
klorpa's avatar
klorpa committed
// wrapped in a closure so as not to pollute the global namespace
vas's avatar
vas committed
// the widgets are generic enough to be reusable; if similar user interfaces are ported to JS, we could move the classes to the global scope
vas's avatar
vas committed

globalThis.rulesAssistantOptions = (function() {
vas's avatar
vas committed
	"use strict";
	const noDefaultSetting = {value: "!NDS!", text: "no default setting"};
ezsh's avatar
ezsh committed
	/** @type {App.RA.Rule} */
vas's avatar
vas committed

vas's avatar
vas committed
	function rulesAssistantOptions(element) {
vas's avatar
vas committed
		V.nextButton = "Back to Main";
		V.nextLink = "Main";
		V.returnTo = "Main";
		V.showEncyclopedia = 1;
		V.encyclopedia = "Personal Assistant";
		if (V.currentRule !== null) {
			const idx = V.defaultRules.findIndex(rule => rule.ID === V.currentRule);
DCoded's avatar
DCoded committed
			if (idx === -1) {
				current_rule = V.defaultRules[0];
DCoded's avatar
DCoded committed
			} else {
				current_rule = V.defaultRules[idx];
DCoded's avatar
DCoded committed
			}
vas's avatar
vas committed
	}

	function returnP(e) { return e.keyCode === 13; }
vas's avatar
vas committed

		const rule = emptyDefaultRule();
		V.defaultRules.push(rule);
vas's avatar
vas committed
		V.currentRule = rule.ID;
vas's avatar
vas committed
	}

vas's avatar
vas committed
		const idx = V.defaultRules.findIndex(rule => rule.ID === current_rule.ID);
vas's avatar
vas committed
		V.defaultRules.splice(idx, 1);
		if (V.defaultRules.length > 0) {
			const new_idx = idx < V.defaultRules.length ? idx : V.defaultRules.length - 1;
			V.currentRule = V.defaultRules[new_idx].ID;
DCoded's avatar
DCoded committed
		} else {
			V.currentRule = null;
		}
vas's avatar
vas committed
	}

DCoded's avatar
DCoded committed
		if (V.defaultRules.length === 1) { return; } // nothing to swap with
vas's avatar
vas committed
		const idx = V.defaultRules.findIndex(rule => rule.ID === current_rule.ID);
DCoded's avatar
DCoded committed
		if (idx === 0) { return; } // no lower rule
brickode's avatar
brickode committed
		arraySwap(V.defaultRules, idx, idx - 1);
vas's avatar
vas committed
	}

DCoded's avatar
DCoded committed
		if (V.defaultRules.length === 1) { return; } // nothing to swap with
vas's avatar
vas committed
		const idx = V.defaultRules.findIndex(rule => rule.ID === current_rule.ID);
DCoded's avatar
DCoded committed
		if (idx === V.defaultRules.length - 1) { return; } // no higher rule
brickode's avatar
brickode committed
		arraySwap(V.defaultRules, idx, idx + 1);
vas's avatar
vas committed
	}

DCoded's avatar
DCoded committed
		if (name === current_rule.name) { return; }
vas's avatar
vas committed
		current_rule.name = name;
vas's avatar
vas committed
	}

	// reload the passage
vas's avatar
vas committed
		const elem = root.element;
vas's avatar
vas committed
		elem.innerHTML = "";
vas's avatar
vas committed
		rulesAssistantOptions(elem);
vas's avatar
vas committed
	}

vas's avatar
vas committed
	const parse = {
		integer(string) {
			let n = parseInt(string, 10);
brickode's avatar
brickode committed
			return isNaN(n) ? 0 : n;
vas's avatar
vas committed
		},
		boobs(string) {
			return Math.clamp(parse.integer(string), 0, 48000);
		},
		butt(string) {
x's avatar
x committed
			return Math.clamp(parse.integer(string), 0, 20);
vas's avatar
vas committed
		},
		lips(string) {
			return Math.clamp(parse.integer(string), 0, 100);
		},
		dick(string) {
x's avatar
x committed
			return Math.clamp(parse.integer(string), 0, 30);
vas's avatar
vas committed
		},
		balls(string) {
x's avatar
x committed
			return Math.clamp(parse.integer(string), 0, 125);
vas's avatar
vas committed
		},
	};

vas's avatar
vas committed
	// the Element class wraps around a DOM element and adds extra functionality
	// this is safer than extending DOM objects directly
	// it also turns DOM manipulation into an implementation detail
	class Element {
		constructor(...args) {
vas's avatar
vas committed
			this.parent = null;
			this.element = this.render(...args);
			this.children = [];
vas's avatar
vas committed
		}

ezsh's avatar
ezsh committed
		/**
		 * @param {Element} child
		 */
vas's avatar
vas committed
		appendChild(child) {
vas's avatar
vas committed
			child.parent = this;
			this.children.push(child);
ezsh's avatar
ezsh committed
			child._appendContentTo(this.element);
vas's avatar
vas committed
			this.element.appendChild(child.element);
vas's avatar
vas committed
		}

ezsh's avatar
ezsh committed
		/**
		 * returns the first argument to simplify creation of basic container items
		 * @returns {*}
		 */
vas's avatar
vas committed
		render(...args) {
vas's avatar
vas committed
			return args[0];
vas's avatar
vas committed
		}

		remove() {
			const idx = this.parent.children.findIndex(child => child === this);
			this.parent.children.slice(idx, 1);
			this.element.remove();
		}
ezsh's avatar
ezsh committed

		/**
		 * @protected
		 * @param {HTMLElement} container
		 */
		_appendContentTo(container) {
			container.appendChild(this.element);
		}
vas's avatar
vas committed
	}
klorpa's avatar
klorpa committed

vas's avatar
vas committed
	class Section extends Element {
brickode's avatar
brickode committed
		constructor(header, hidden = false) {
vas's avatar
vas committed
			super(header);
			this.hidey = this.element.querySelector("div");
DCoded's avatar
DCoded committed
			if (hidden) { this.toggle_hidey(); }
vas's avatar
vas committed
		}
klorpa's avatar
klorpa committed

vas's avatar
vas committed
		render(header) {
			const section = document.createElement("section");
			section.classList.add("rajs-section");
			const h1 = document.createElement("h1");
brickode's avatar
brickode committed
			h1.onclick = () => { this.toggle_hidey(); };
vas's avatar
vas committed
			h1.innerHTML = header;
			const hidey = document.createElement("div");
			section.appendChild(h1);
			section.appendChild(hidey);
			return section;
		}

		appendChild(child) {
			child.parent = this;
			this.children.push(child);
ezsh's avatar
ezsh committed
			child._appendContentTo(this.hidey);
vas's avatar
vas committed
		}

		toggle_hidey() {
brickode's avatar
brickode committed
			switch (this.hidey.style.display) {
vas's avatar
vas committed
				case "none":
					this.hidey.style.display = "initial";
					break;
				default:
					this.hidey.style.display = "none";
					break;
			}
		}
	}
vas's avatar
vas committed

	class Tab extends Element {
		/**
		 *
		 * @param {string} name
		 * @param {string} label
		 * @param {HTMLDivElement} tabButtonsContainer
		 */
		constructor(name, label, tabButtonsContainer) {
			super(name);
			tabButtonsContainer.appendChild(Tab.makeTabButton(name, label));
		}
		render(name) {
			const tab = document.createElement("div");
			tab.id = name;
			tab.className = "tabcontent";

			this.tabContent_ = document.createElement("div");
Loading
Loading full blame...