From 026d910c395500e4ab841a5203b4028c878466e4 Mon Sep 17 00:00:00 2001
From: Arkerthan <arkerthan@gmail.com>
Date: Tue, 3 Mar 2020 16:52:24 +0100
Subject: [PATCH] convert tab version of App.SlaveList.penthouse() to DOM

---
 src/gui/css/mainStyleSheet.css |  10 ++
 src/js/slaveListing.js         | 192 ++++++++++++++++++---------------
 2 files changed, 114 insertions(+), 88 deletions(-)

diff --git a/src/gui/css/mainStyleSheet.css b/src/gui/css/mainStyleSheet.css
index 886b6e7f0f7..d61e54a15f8 100644
--- a/src/gui/css/mainStyleSheet.css
+++ b/src/gui/css/mainStyleSheet.css
@@ -391,3 +391,13 @@ h3 + p {
 	font-weight: bold;
 	color: red;
 }
+
+div.center {
+	margin-left: auto;
+	margin-right: auto;
+	text-align: center;
+}
+
+div.flex-container {
+	display: flex;
+}
diff --git a/src/js/slaveListing.js b/src/js/slaveListing.js
index 7c85af96b40..ccde18a0dab 100644
--- a/src/js/slaveListing.js
+++ b/src/js/slaveListing.js
@@ -590,6 +590,31 @@ App.UI.SlaveList.sortingLinks = function(passage) {
 	return r;
 };
 
+/**
+ * @param {string} passage
+ * @returns {*}
+ */
+App.UI.SlaveList.sortingLinksDOM = function(passage) {
+	const outerDiv = document.createElement("div");
+	outerDiv.classList.add("flex-container");
+	const textify = string => capFirstChar(string.replace(/([A-Z])/g, " $1"));
+
+	let innerDiv = App.UI.DOM.makeElement("div", "Sort by: ", "indent");
+	let order = ["devotion", "name", "assignment", "seniority", "actualAge", "visualAge", "physicalAge", "weeklyIncome"]
+		.map(so => V.sortSlavesBy !== so ?
+			App.UI.DOM.passageLink(textify(so), passage, () => {V.sortSlavesBy = so;}) : textify(so));
+	innerDiv.append(App.UI.DOM.arrayToList(order, " | ", " | "));
+	outerDiv.append(innerDiv);
+
+	innerDiv = App.UI.DOM.makeElement("div", "Sort: ", "indent");
+	order = ["descending", "ascending"].map(so => V.sortSlavesOrder !== so ?
+		App.UI.DOM.passageLink(textify(so), passage, () => {V.sortSlavesOrder = so;}) : textify(so));
+	innerDiv.append(App.UI.DOM.arrayToList(order, " | ", " | "));
+	outerDiv.append(innerDiv);
+
+	return outerDiv;
+};
+
 /**
  * Standard tabs for a facility with a single job (SJ)
  * @param {App.Entity.Facilities.Facility} facility
@@ -769,124 +794,114 @@ App.UI.SlaveList.penthousePage = function() {
 	const ph = App.Entity.facilities.penthouse;
 	const listElementId = 'summarylist'; // for the untabbed mode only
 
-	function span(text, cls, id) {
-		return `<span${cls ? ` class="${cls}"` : ''}${id ? ` id="${id}"` : ''}>${text}</span>`;
-	}
-
 	function overviewTabContent() {
-		let r = '';
-		const thisArcology = V.arcologies[0];
+		const fragment = document.createDocumentFragment();
+		const A = V.arcologies[0];
 
+		let slaveWrapper = document.createElement("div"); // first is a div so we have space between slave and buttons
 		if (V.HeadGirl) {
 			/** @type {App.Entity.SlaveState} */
 			const HG = V.HeadGirl;
-			r += `${span(SlaveFullName(HG), "emphasizedSlave pink")} is serving as your Head Girl`;
-			if (thisArcology.FSEgyptianRevivalistLaw === 1) {
-				r += ' and Consort';
+			slaveWrapper.append(App.UI.DOM.makeElement("span", SlaveFullName(HG), "slave-name"),
+				" is serving as your Head Girl");
+			if (A.FSEgyptianRevivalistLaw === 1) {
+				slaveWrapper.append(" and Consort");
 			}
-			r += `. <strong> ${span(App.UI.passageLink("Manage Head Girl", "HG Select"), null, "manageHG")}</strong> ${span("[H]", "cyan")}`;
-			r += App.UI.SlaveList.render.listMarkup([App.Utils.slaveIndexForId(HG.ID)], [],
-				App.UI.SlaveList.SlaveInteract.penthouseInteract);
+			slaveWrapper.append(". ");
+			const link = App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Manage Head Girl", "HG Select"), "major-link");
+			link.id = "manageHG";
+			slaveWrapper.append(link, " ", App.UI.DOM.makeElement("span", "[H]", "hotkey"));
+			slaveWrapper.append(App.UI.SlaveList.render.listDOM([App.Utils.slaveIndexForId(HG.ID)], [],
+				App.UI.SlaveList.SlaveInteract.penthouseInteract));
 		} else {
 			if (V.slaves.length > 1) {
-				r += `You have ${span("not", "red")} selected a Head Girl`;
-				if (thisArcology.FSEgyptianRevivalistLaw === 1) {
-					r += ' and Consort';
+				slaveWrapper.append("You have ", App.UI.DOM.makeElement("span", "not", "warning"), " selected a Head Girl");
+				if (A.FSEgyptianRevivalistLaw === 1) {
+					slaveWrapper.append(" and Consort");
 				}
-				r += `. <strong>${span(App.UI.passageLink("Select One", "HG Select"), null, "manageHG")}</strong> ${span("[H]", "cyan")}`;
+				slaveWrapper.append(". ", App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Select One", "HG Select"), "major-link"),
+					" ", App.UI.DOM.makeElement("span", "[H]", "hotkey"));
+				slaveWrapper.id = "manageHG";
 			} else {
-				r += '<em>You do not have enough slaves to keep a Head Girl</em>';
+				slaveWrapper.append("You do not have enough slaves to keep a Head Girl");
+				slaveWrapper.classList.add("note");
 			}
 		}
-		r += '<br>';
+		fragment.append(slaveWrapper);
 
+		slaveWrapper = document.createElement("p");
 		if (V.Recruiter) {
 			/** @type {App.Entity.SlaveState} */
 			const RC = V.Recruiter;
-			const p = getPronouns(RC);
-			r += `${span(SlaveFullName(RC), "emphasizedSlave pink")} is working `;
+			const {he} = getPronouns(RC);
+			slaveWrapper.append(App.UI.DOM.makeElement("span", SlaveFullName(RC), "slave-name"),
+				" is working");
 			if (V.recruiterTarget !== "other arcologies") {
-				r += 'to recruit girls';
+				slaveWrapper.append(" to recruit girls");
 			} else {
-				r += 'as a Sexual Ambassador';
-				if (thisArcology.influenceTarget === -1) {
-					r += ', but ' + span(p.object + ' has no target to influence', "red");
+				slaveWrapper.append(" as a Sexual Ambassador");
+				if (A.influenceTarget === -1) {
+					slaveWrapper.append(", but ", App.UI.DOM.makeElement("span", `${he} has no target to influence.`, "warning"));
 				} else {
-					const targetName = V.arcologies.find(a => a.direction === thisArcology.influenceTarget).name;
-					r += ' to ' + targetName;
+					const targetName = V.arcologies.find(a => a.direction === A.influenceTarget).name;
+					slaveWrapper.append(` to ${targetName}.`);
 				}
 			}
-			r += `${span('. <strong>' + App.UI.passageLink("Manage Recruiter", "Recruiter Select") + '</strong>', null, "manageRecruiter")} ${span("[U]", "cyan")}`;
-			r += App.UI.SlaveList.render.listMarkup([App.Utils.slaveIndexForId(RC.ID)], [],
-				App.UI.SlaveList.SlaveInteract.penthouseInteract);
+			slaveWrapper.append(". ");
+			const link = App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Manage Recruiter", "Recruiter Select"), "major-link");
+			link.id = "manageRecruiter";
+			slaveWrapper.append(link, " ", App.UI.DOM.makeElement("span", "[U]", "hotkey"));
+			slaveWrapper.append(App.UI.SlaveList.render.listDOM([App.Utils.slaveIndexForId(RC.ID)], [],
+				App.UI.SlaveList.SlaveInteract.penthouseInteract));
 		} else {
-			r += `You have ${span("not", "red")} selected a Recruiter. `;
-			r += `${span('<strong>' + App.UI.passageLink("Select one", "Recruiter Select") + '</strong>', null, "manageRecruiter")} ${span("[U]", "cyan")}`;
+			slaveWrapper.append("You have ", App.UI.DOM.makeElement("span", "not", "warning"), " selected a Recruiter. ",
+				App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Select one", "Recruiter Select"), "major-link"),
+				" ", App.UI.DOM.makeElement("span", "[U]", "hotkey"));
+			slaveWrapper.id = "manageRecruiter";
 		}
+		fragment.append(slaveWrapper);
 
 		if (V.dojo) {
-			r += '<br>';
+			slaveWrapper = document.createElement("p");
 			/** @type {App.Entity.SlaveState} */
 			const BG = V.Bodyguard;
 			if (BG) {
-				r += `${span(SlaveFullName(BG), "emphasizedSlave pink")} is serving as your bodyguard. `;
-				r += span(`<strong>${App.UI.passageLink("Manage Bodyguard", "BG Select")}</strong> `, null, "manageBG") +
-					span("[B]", "cyan");
-				r += App.UI.SlaveList.render.listMarkup([App.Utils.slaveIndexForId(BG.ID)], [],
-					App.UI.SlaveList.SlaveInteract.penthouseInteract);
+				slaveWrapper.append(App.UI.DOM.makeElement("span", SlaveFullName(BG), "slave-name"),
+					" is serving as your bodyguard. ");
+				const link = App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Manage Bodyguard", "BG Select"), "major-link");
+				link.id = "manageBG";
+				slaveWrapper.append(link, " ", App.UI.DOM.makeElement("span", "[B]", "hotkey"));
+				slaveWrapper.append(App.UI.SlaveList.render.listDOM([App.Utils.slaveIndexForId(BG.ID)], [],
+					App.UI.SlaveList.SlaveInteract.penthouseInteract));
 			} else {
-				r += `You have ${span("not", "red")} selected a Bodyguard. `;
-				r += span(`<strong>${App.UI.passageLink("Select one", "BG Select")}</strong> `, null, "manageBG") +
-					span("[B]", "cyan");
+				slaveWrapper.append("You have ", App.UI.DOM.makeElement("span", "not", "warning"), " selected a Bodyguard. ",
+					App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Select one", "BG Select"), "major-link"),
+					" ", App.UI.DOM.makeElement("span", "[B]", "hotkey"));
+				slaveWrapper.id = "manageBG";
 			}
 
-			/* Start Italic event text */
 			if (BG && BG.assignment === "guard you") {
-				const p = getPronouns(BG);
-				V.i = App.Utils.slaveIndexForId(BG.ID);
-				const interactLinkSetters = `$activeSlave = $slaves[${V.i}], $nextButton = "Back", $nextLink = "AS Dump", $returnTo = "Main"`;
-				r += `<br><span class='scene-intro'>${App.Interact.guardPose(BG)}</span>`;
-				let useHimLinks = [];
-				useHimLinks.push(App.UI.passageLink(`Use ${p.his} mouth`, "FLips", interactLinkSetters));
-				useHimLinks.push(App.UI.passageLink(`Play with ${p.his} tits`, "FBoobs", interactLinkSetters));
-				if (canDoVaginal(BG)) {
-					useHimLinks.push(App.UI.passageLink(`Fuck ${p.him}`, "FVagina", interactLinkSetters));
-					if (canDoAnal(BG)) {
-						useHimLinks.push(App.UI.passageLink(`Use ${p.his} holes`, "FButt", interactLinkSetters));
-					}
-					if (BG.belly >= 300000) {
-						useHimLinks.push(App.UI.passageLink(`Fuck ${p.him} over ${p.his} belly`, "FBellyFuck", interactLinkSetters));
-					}
-				}
-				/* check */
-				if (canPenetrate(BG)) {
-					useHimLinks.push(App.UI.passageLink(`Ride ${p.him}`, "FDick", interactLinkSetters));
-				}
-				if (canDoAnal(BG)) {
-					useHimLinks.push(App.UI.passageLink(`Fuck ${p.his} ass`, "FAnus", interactLinkSetters));
-				}
-				useHimLinks.push(App.UI.passageLink(`Abuse ${p.him}`, "Gameover", '$gameover ="idiot ball"'));
-
-				r += `<br>&nbsp;&nbsp;&nbsp;&nbsp;${useHimLinks.join('&thinsp;|&thinsp;')}`;
-				/* End Italic event text */
+				slaveWrapper.append(App.MainView.useGuard());
 			}
-			r += "<br/>";
+			fragment.append(slaveWrapper);
 		}
-		return r;
+		return fragment;
 	}
 
 	/**
 	 * @param {string} job
-	 * @returns {{n: number, text: string}}
+	 * @returns {{n: number, dom: DocumentFragment}}
 	 */
 	function _slavesForJob(job) {
 		const employeesIndices = job === 'all' ? ph.employeesIndices() : ph.job(job).employeesIndices();
-		if (employeesIndices.length === 0) { return {n: 0, text: ''}; }
+		if (employeesIndices.length === 0) {
+			return {n: 0, dom: document.createDocumentFragment()};
+		}
 
 		SlaveSort.indices(employeesIndices);
 		return {
 			n: employeesIndices.length,
-			text: App.UI.SlaveList.render.listMarkup(employeesIndices, [], App.UI.SlaveList.SlaveInteract.penthouseInteract)
+			dom: App.UI.SlaveList.render.listDOM(employeesIndices, [], App.UI.SlaveList.SlaveInteract.penthouseInteract)
 		};
 	}
 
@@ -923,13 +938,13 @@ App.UI.SlaveList.penthousePage = function() {
 	 * @typedef tabDesc
 	 * @property {string} tabName
 	 * @property {string} caption
-	 * @property {string} content
+	 * @property {Node} content
 	 */
 
 	/**
 	 * @param {string} tabName
 	 * @param {string} caption
-	 * @param {string} content
+	 * @param {Node} content
 	 * @returns {tabDesc}
 	 */
 	function makeTabDesc(tabName, caption, content) {
@@ -942,7 +957,7 @@ App.UI.SlaveList.penthousePage = function() {
 
 	/**
 	 * Displays encyclopedia entries for occupations at the top of the tab, if enabled
-	 * @returns {string}
+	 * @returns {HTMLSpanElement}
 	 */
 	function encycTips(jn) {
 		const span = document.createElement("span");
@@ -986,17 +1001,17 @@ App.UI.SlaveList.penthousePage = function() {
 					break;
 			}
 		}
-		return App.UI.DOM.includeDOM(span, "ency" + jn);
+		return span;
 	}
 
-	let r = '';
+	let fragment = document.createDocumentFragment();
 
 	if (V.positionMainLinks >= 0) {
-		r += '<center>' + App.UI.DOM.includeDOM(App.UI.View.mainLinks(), "mainLinks") + '</center><br>';
+		fragment.append(App.UI.DOM.makeElement("div", App.UI.View.mainLinks(), "center"));
 	}
 
 	if (V.sortSlavesMain) {
-		r += '<br>' + this.sortingLinks("Main") + '<br>';
+		fragment.append(this.sortingLinksDOM("Main"));
 	}
 
 	if (V.useSlaveSummaryTabs) {
@@ -1012,7 +1027,7 @@ App.UI.SlaveList.penthousePage = function() {
 		for (const jn of ph.jobsNames) {
 			const slaves = _slavesForJob(jn);
 			if (slaves.n > 0) {
-				tabs.push(makeTabDesc(jn, `${ph.desc.jobs[jn].position} (${slaves.n})`, encycTips(jn) + slaves.text));
+				tabs.push(makeTabDesc(jn, `${ph.desc.jobs[jn].position} (${slaves.n})`, App.UI.DOM.combineNodes(encycTips(jn), slaves.dom)));
 			}
 		}
 
@@ -1020,17 +1035,18 @@ App.UI.SlaveList.penthousePage = function() {
 		const penthouseSlavesIndices = ph.employeesIndices();
 		SlaveSort.indices(penthouseSlavesIndices);
 		tabs.push(makeTabDesc('all', `All (${penthouseSlavesIndices.length})`,
-			this.render.listMarkup(penthouseSlavesIndices, [], App.UI.SlaveList.SlaveInteract.penthouseInteract)));
+			this.render.listDOM(penthouseSlavesIndices, [], App.UI.SlaveList.SlaveInteract.penthouseInteract)));
 
 
-		r += '<div class="tab">';
+		const div = document.createElement("div");
+		div.classList.add("tab");
 		for (const tab of tabs) {
-			r += App.UI.tabbar.tabButton(tab.tabName, tab.caption);
+			div.append(App.UI.tabbar.tabButtonDOM(tab.tabName, tab.caption));
 		}
-		r += '</div>';
+		fragment.append(div);
 
 		for (const tab of tabs) {
-			r += App.UI.tabbar.makeTab(tab.tabName, tab.content);
+			fragment.append(App.UI.tabbar.makeTabDOM(tab.tabName, tab.content));
 		}
 	} else {
 		State.temporary.mainPageUpdate = {
@@ -1043,11 +1059,11 @@ App.UI.SlaveList.penthousePage = function() {
 	}
 
 	if (V.positionMainLinks <= 0) {
-		r += '<br><center>' + App.UI.DOM.includeDOM(App.UI.View.mainLinks(), "mainLinks") + '</center>';
+		fragment.append(App.UI.DOM.makeElement("div", App.UI.View.mainLinks(), "center"));
 	}
 
 	App.UI.tabbar.handlePreSelectedTab();
-	return r;
+	return App.UI.DOM.includeDOM(fragment, "penthouseDOM");
 };
 
 /**
-- 
GitLab