From 99c884b6eb50698f0c809db81624388c373159dc Mon Sep 17 00:00:00 2001
From: Arkerthan <arkerthan@gmail.com>
Date: Tue, 3 Mar 2020 14:04:56 +0100
Subject: [PATCH] convert mainLinks to DOM

---
 src/002-config/mousetrapConfig.js |   4 +-
 src/gui/css/mainStyleSheet.css    |   4 +
 src/interaction/main/mainLinks.js | 226 +++++++++++++++++++-----------
 src/js/slaveListing.js            |   4 +-
 4 files changed, 153 insertions(+), 85 deletions(-)

diff --git a/src/002-config/mousetrapConfig.js b/src/002-config/mousetrapConfig.js
index bae8064f053..1007d1f0727 100644
--- a/src/002-config/mousetrapConfig.js
+++ b/src/002-config/mousetrapConfig.js
@@ -54,10 +54,10 @@ Mousetrap.bind("h", function() {
 	$("#manageHG a").trigger("click");
 });
 Mousetrap.bind("s", function() {
-	$("#buySlaves a.macro-link").trigger("click");
+	$("#buySlaves a").trigger("click");
 });
 Mousetrap.bind("a", function() {
-	$("#managePA a.macro-link").trigger("click");
+	$("#managePA a").trigger("click");
 });
 Mousetrap.bind("b", function() {
 	$("#manageBG a").trigger("click");
diff --git a/src/gui/css/mainStyleSheet.css b/src/gui/css/mainStyleSheet.css
index 9e98b1be2a7..886b6e7f0f7 100644
--- a/src/gui/css/mainStyleSheet.css
+++ b/src/gui/css/mainStyleSheet.css
@@ -373,6 +373,10 @@ h3 + p {
 	margin: 0 auto;
 }
 
+.major-link {
+	font-weight: bold;
+}
+
 .clear-formatting {
 	color: white;
 	font-weight: normal;
diff --git a/src/interaction/main/mainLinks.js b/src/interaction/main/mainLinks.js
index 7347394b225..816a2fa5686 100644
--- a/src/interaction/main/mainLinks.js
+++ b/src/interaction/main/mainLinks.js
@@ -1,121 +1,142 @@
-/* OPEN MAIN */
-App.UI.View.MainLinks = function() {
+/**
+ * @returns {DocumentFragment}
+ */
+App.UI.View.mainLinks = function() {
 	"use strict";
 	const PA = Array.isArray(V.personalAttention) ? V.personalAttention.map(x => getSlave(x.ID)) : [];
-	let r = '';
+	let fragment = document.createDocumentFragment();
 
 	if (V.PC.health.shortDamage >= 30) {
-		r += `The injuries received in the recent battle prevent you from undertaking tiring efforts.`;
+		fragment.append(`The injuries received in the recent battle prevent you from undertaking tiring efforts.`);
 	} else {
 		switch (V.personalAttention) {
 			case "business":
-				r += `You plan to focus on business this week.`;
+				fragment.append(`You plan to focus on business this week.`);
 				break;
 			case "whoring":
-				r += `You plan to focus on earning extra money this week.`;
+				fragment.append(`You plan to focus on earning extra money this week.`);
 				break;
 			case "upkeep":
-				r += `You plan to focus on cleaning the penthouse this week.`;
+				fragment.append(`You plan to focus on cleaning the penthouse this week.`);
 				break;
 			case "defensive survey":
-				r += `You plan to survey ${V.arcologies[0].name}'s defenses in person this week.`;
+				fragment.append(`You plan to survey ${V.arcologies[0].name}'s defenses in person this week.`);
 				break;
 			case "development project":
-				r += `You plan on contributing to a local development project this week.`;
+				fragment.append(`You plan on contributing to a local development project this week.`);
 				break;
 			case "smuggling":
-				r += `You plan to make some easy (but dirty) money this week.`;
+				fragment.append(`You plan to make some easy (but dirty) money this week.`);
 				break;
 			case "HG":
-				r += `You plan to support your Head Girl this week, `;
+				fragment.append(`You plan to support your Head Girl this week, `);
 				if (V.HeadGirl) {
 					const {he, his} = getPronouns(V.HeadGirl);
-					r += `so ${he} can give more slaves ${his} attention.`;
+					fragment.append(`so ${he} can give more slaves ${his} attention.`);
 				} else {
-					r += `should you assign one.`;
+					fragment.append(`should you assign one.`);
 				}
 				break;
 			case "sex":
-				r += `You plan to have as much sex with your slaves as possible this week.`;
+				fragment.append(`You plan to have as much sex with your slaves as possible this week.`);
 				break;
 			case "trading":
-				r += `This week you will learn trading.`;
+				fragment.append(`This week you will learn trading.`);
 				break;
 			case "warfare":
-				r += `This week you will learn modern combat tactics.`;
+				fragment.append(`This week you will learn modern combat tactics.`);
 				break;
 			case "slaving":
-				r += `This week you will learn slaving.`;
+				fragment.append(`This week you will learn slaving.`);
 				break;
 			case "engineering":
-				r += `This week you will learn engineering.`;
+				fragment.append(`This week you will learn engineering.`);
 				break;
 			case "medicine":
-				r += `This week you will learn medicine.`;
+				fragment.append(`This week you will learn medicine.`);
 				break;
 			case "hacking":
-				r += `This week you will learn hacking.`;
+				fragment.append(`This week you will learn hacking.`);
 				break;
 			case "proclamation":
-				r += `This week you plan to issue a proclamation about ${V.SecExp.proclamation.type}.`;
+				fragment.append(`This week you plan to issue a proclamation about ${V.SecExp.proclamation.type}.`);
 				break;
 			case "technical accidents":
-				r += `This week you plan to sell your technical skills to the highest bidder.`;
+				fragment.append(`This week you plan to sell your technical skills to the highest bidder.`);
 				break;
 			default:
 				if (PA.length > 0) {
-					r += `You plan to train `;
-					let l = PA.length;
-					for (let dwi = 0; dwi < l; dwi++) {
-						if (dwi > 0 && dwi === l - 1) {
-							r += ` and `;
-						}
-						r += `<strong><u><span class="pink">${SlaveFullName(PA[dwi])}</span></u></strong> to ${V.personalAttention[dwi].trainingRegimen}`;
-						if (dwi > 0 && dwi < l - 2) {
-							r += `,`;
+					fragment.append(`You plan to train `);
+
+					const trainees = [];
+					PA.forEach((trainee, i) => {
+							trainees.push(App.UI.DOM.combineNodes(App.UI.DOM.makeElement("span", SlaveFullName(trainee), "slave-name"),
+								` to ${V.personalAttention[i].trainingRegimen}`));
 						}
-					}
-					r += ` this week.`;
+					);
+					fragment.append(App.UI.DOM.arrayToList(trainees));
+
+					fragment.append(` this week.`);
 				}
 				break;
 		}
 	}
 
 	if (V.PC.health.shortDamage < 30) {
-		r += ` <span id="managePA"><strong>${App.UI.passageLink("Change plans", "Personal Attention Select")}</strong></span> <span class="cyan">[A]</span>`;
+		const link = App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Change plans", "Personal Attention Select"), "major-link");
+		link.id = "managePA";
+		fragment.append(" ", link, " ", App.UI.DOM.makeElement("span", "[A]", "hotkey"));
 	}
 
 	if (V.useSlaveSummaryOverviewTab !== 1) {
+		let div = document.createElement("div");
 		if (typeof V.slaveIndices[V.HeadGirl.ID] !== 'undefined') {
-			r += `<br><strong><u><span class="pink">${SlaveFullName(V.HeadGirl)}</span></u></strong> is serving as your Head Girl`;
+			div.append(App.UI.DOM.makeElement("span", SlaveFullName(V.HeadGirl), "slave-name"), " is serving as your Head Girl");
 			if (V.arcologies[0].FSEgyptianRevivalistLaw === 1) {
-				r += ` and Consort`;
+				div.append(` and Consort`);
 			}
-			r += `. <span id="manageHG"><strong>${App.UI.passageLink("Manage Head Girl", "HG Select")}</strong></span> <span class="cyan">[H]</span>`;
-		} else if (typeof V.slaveIndices[V.HeadGirl.ID] === 'undefined' && (V.slaves.length > 1)) {
-			r += `<br>You have not selected a Head Girl`;
+			div.append(". ",
+				App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Manage Head Girl", "HG Select"), "major-link"),
+				" ", App.UI.DOM.makeElement("span", "[H]", "hotkey"));
+			div.id = "manageHG";
+		} else if (V.slaves.length > 1) {
+			div.append(`You have not selected a Head Girl`);
 			if (V.arcologies[0].FSEgyptianRevivalistLaw === 1) {
-				r += ` and Consort`;
+				div.append(` and Consort`);
 			}
-			r += `. <span id="manageHG"><strong>${App.UI.passageLink("Select one", "HG Select")}</strong></span> <span class="cyan">[H]</span>`;
-		} else if (typeof V.slaveIndices[V.HeadGirl.ID] === 'undefined') {
-			r += `<br><span class="note">You do not have enough slaves to keep a Head Girl</span>`;
+			div.append(". ",
+				App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Select One", "HG Select"), "major-link"),
+				" ", App.UI.DOM.makeElement("span", "[H]", "hotkey"));
+			div.id = "manageHG";
+		} else {
+			div.append(App.UI.DOM.makeElement("span", "You do not have enough slaves to keep a Head Girl", "note"));
 		}
-		r += `<br>`;
+		fragment.append(div);
 
+		div = document.createElement("div");
 		if (typeof V.slaveIndices[V.Recruiter.ID] !== 'undefined') {
-			r += `<strong><u><span class="pink">${SlaveFullName(V.Recruiter)}</span></u></strong> is working to recruit girls. <span id="manageRecruiter"><strong>${App.UI.passageLink("Manage Recruiter", "Recruiter Select")}</strong></span> <span class="cyan">[U]</span>`;
+			div.append(App.UI.DOM.makeElement("span", SlaveFullName(V.Recruiter), "slave-name"), " is working to recruit girls. ",
+				App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Manage Recruiter", "Recruiter Select"), "major-link"));
 		} else {
-			r += `You have not selected a Recruiter. <span id="manageRecruiter"><strong>${App.UI.passageLink("Select one", "Recruiter Select")}</strong></span> <span class="cyan">[U]</span>`;
+			div.append("You have not selected a Recruiter. ",
+				App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Select one", "Recruiter Select"), "major-link"));
 		}
+		div.append(" ", App.UI.DOM.makeElement("span", "[U]", "hotkey"));
+		div.id = "manageRecruiter";
+		fragment.append(div);
 
 		if (V.dojo) {
-			r += `<br>`;
+			div = document.createElement("div");
 			if (typeof V.slaveIndices[V.Bodyguard.ID] !== 'undefined') {
-				r += `<strong><u><span class="pink">${SlaveFullName(V.Bodyguard)}</span></u></strong> is serving as your bodyguard. <span id="manageBG"><strong>${App.UI.passageLink("Manage Bodyguard", "BG Select")}</strong></span> <span class="cyan">[B]</span>`;
+				div.append(App.UI.DOM.makeElement("span", SlaveFullName(V.Bodyguard), "slave-name"), " is serving as your bodyguard. ",
+					App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Manage Bodyguard", "BG Select"), "major-link"));
 			} else {
-				r += `You have not selected a Bodyguard. <span id="manageBG"><strong>${App.UI.passageLink("Select one", "BG Select")}</strong></span> <span class="cyan">[B]</span>`;
+				div.append("You have not selected a Bodyguard. ",
+					App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Select one", "BG Select"), "major-link"));
 			}
+			div.append(" ", App.UI.DOM.makeElement("span", "[B]", "hotkey"));
+			div.id = "manageBG";
+			fragment.append(div);
 		}
 	}
 
@@ -129,19 +150,24 @@ App.UI.View.MainLinks = function() {
 			const slaveOrgans = V.completedOrgans.reduce((acc, organ) => organ.ID === V.slaves[i].ID ? acc + 1 : acc, 0);
 			/* if the interrogated slave has one or more organs ready: */
 			if (slaveOrgans > 0) {
-				r += '<br><span class="yellow">The fabricator has completed ';
+				const div = document.createElement("div");
+				div.classList.add("yellow");
+				div.append("The fabricator has completed ");
 				if (slaveOrgans > 1) {
-					r += `${slaveOrgans} organs`;
+					div.append(`${slaveOrgans} organs`);
 				} else {
-					r += 'an organ';
+					div.append('an organ');
 				}
-				r += ` for </span>${App.UI.link(V.slaves[i].slaveName, () => { V.activeSlave = V.slaves[i]; }, [], "Slave Interact")}, <span class="yellow">which `;
+				div.append(" for ",
+					App.UI.DOM.makeElement("span", App.UI.link(V.slaves[i].slaveName, () => { V.activeSlave = V.slaves[i]; }, [], "Slave Interact"), "clear-formatting"),
+					" which ");
 				if (slaveOrgans > 1) {
-					r += 'are';
+					div.append('are');
 				} else {
-					r += 'is';
+					div.append('is');
 				}
-				r += ' ready to be implanted.</span>';
+				div.append(' ready to be implanted.');
+				fragment.append(div);
 			}
 		}
 	}
@@ -151,7 +177,12 @@ App.UI.View.MainLinks = function() {
 			if (getSlave(V.adjustProsthetics[j].slaveID) !== undefined) {
 				const i = V.slaveIndices[V.adjustProsthetics[j].slaveID];
 				if (V.adjustProsthetics[j].workLeft <= 0) {
-					r += `<br><span class="yellow">The lab has completed ${addA(setup.prosthetics[V.adjustProsthetics[j].id].name)} for</span> <span id="name">${App.UI.link(SlaveFullName(V.slaves[i]), () => { V.activeSlave = V.slaves[i]; }, [], "Slave Interact")},</span> <span class="yellow"> which is ready to be attached.</span>`;
+					const div = document.createElement("div");
+					div.classList.add("yellow");
+					div.append(`The lab has completed ${addA(setup.prosthetics[V.adjustProsthetics[j].id].name)} for `,
+						App.UI.DOM.makeElement("span", App.UI.link(SlaveFullName(V.slaves[i]), () => { V.activeSlave = V.slaves[i]; }, [], "Slave Interact"), "clear-formatting"),
+						" which is ready to be attached.");
+					fragment.append(div);
 				}
 			} else {
 				V.adjustProsthetics.splice(j, 1);
@@ -161,57 +192,90 @@ App.UI.View.MainLinks = function() {
 	}
 
 	if (V.completedOrgans.length > 0 && V.adjustProstheticsCompleted > 0) {
-		r += `<br>${App.UI.passageLink("Implant and Attach", "Multiple Organ Implant")} <span class="yellow">all organs and prosthetics that are ready.</span>`;
+		const div = document.createElement("div");
+		div.append(App.UI.DOM.passageLink("Implant and Attach", "Multiple Organ Implant"),
+			App.UI.DOM.makeElement("span", " all organs and prosthetics that are ready.", "yellow"));
+		fragment.append(div);
 	} else if (V.completedOrgans.length > 1) {
-		r += `<br>${App.UI.passageLink("Implant", "Multiple Organ Implant")} <span class="yellow">all organs that are ready for implantation.</span>`;
+		const div = document.createElement("div");
+		div.append(App.UI.DOM.passageLink("Implant", "Multiple Organ Implant"),
+			App.UI.DOM.makeElement("span", " all organs that are ready for implantation.", "yellow"));
+		fragment.append(div);
 	} else if (V.adjustProstheticsCompleted > 1) {
-		r += `<br>${App.UI.passageLink("Attach", "Multiple Organ Implant")} <span class="yellow">all prosthetics that are ready to be attached.</span>`;
+		const div = document.createElement("div");
+		div.append(App.UI.DOM.passageLink("Attach", "Multiple Organ Implant"),
+			App.UI.DOM.makeElement("span", " all prosthetics that are ready to be attached.", "yellow"));
+		fragment.append(div);
 	}
 
-	if (V.slaveCostFactor > 1.05) {
-		r += `<br><span class="yellow">There is a bull market for slaves; the price of slaves is very high.</span>`;
-	} else if (V.slaveCostFactor > 1) {
-		r += `<br><span class="yellow">The slave market is bullish; the price of slaves is high.</span>`;
-	} else if (V.slaveCostFactor < 0.95) {
-		r += `<br><span class="yellow">There is a bear market for slaves; the price of slaves is very low.</span>`;
-	} else if (V.slaveCostFactor < 1) {
-		r += `<br><span class="yellow">The slave market is bearish; the price of slaves is low.</span>`;
+	const div = document.createElement("div");
+	if (V.slaveCostFactor === 1) {
+		div.append("The slave market is stable; the price of slaves is average.");
 	} else {
-		r += `<br>The slave market is stable; the price of slaves is average.`;
+		let r;
+		if (V.slaveCostFactor > 1) {
+			if (V.slaveCostFactor > 1.05) {
+				r = "There is a bull market for slaves; the price of slaves is very high.";
+			} else {
+				r = "The slave market is bullish; the price of slaves is high.";
+			}
+		} else {
+			if (V.slaveCostFactor < 0.95) {
+				r = "There is a bear market for slaves; the price of slaves is very low.";
+			} else {
+				r = "The slave market is bearish; the price of slaves is low.";
+			}
+		}
+		div.append(App.UI.DOM.makeElement("span", r, "yellow"));
+	}
+
+	const buySlaves = App.UI.DOM.makeElement("span", App.UI.DOM.passageLink("Buy Slaves", "Buy Slaves"), "major-link");
+	buySlaves.id = "buySlaves";
+	div.append(" ", buySlaves, " ", App.UI.DOM.makeElement("span", "[S]", "hotkey"));
+
+	fragment.append(div);
+
+	/**
+	 * @param {string} school
+	 */
+	function schoolSale(school) {
+		const div = document.createElement("div");
+		div.append(App.UI.DOM.makeElement("span", "For your first purchase, ", "yellow"),
+			App.UI.DOM.passageLink(school, school, () => { V.slavesSeen += 1; }),
+			App.UI.DOM.makeElement("span", " will sell at half price this week.", "yellow"));
+		fragment.append(div);
 	}
 
-	r += ` <span id="buySlaves"><strong>${App.UI.passageLink("Buy Slaves", "Buy Slaves")}</strong></span> <span class="cyan">[S]</span>`;
 	if (V.seeDicks !== 100) {
 		if (V.TSS.schoolSale !== 0) {
-			r += `<br><span class="yellow">For your first purchase, </span><strong>[[The Slavegirl School][$slavesSeen += 1]]</strong><span class="yellow"> will sell at half price this week.</span>`;
+			schoolSale("The Slavegirl School");
 		}
 		if (V.GRI.schoolSale !== 0) {
-			r += `<br><span class="yellow">For your first purchase, </span><strong>[[Growth Research Institute][$slavesSeen += 1]]</strong><span class="yellow"> will sell at half price this week.</span>`;
+			schoolSale("Growth Research Institute");
 		}
 		if (V.SCP.schoolSale !== 0) {
-			r += `<br><span class="yellow">For your first purchase, </span><strong>[[St. Claver Preparatory][$slavesSeen += 1]]</strong><span class="yellow"> will sell at half price this week.</span>`;
+			schoolSale("St. Claver Preparatory");
 		}
 		if (V.TCR.schoolSale !== 0) {
-			r += `<br><span class="yellow">For your first purchase, </span><strong>[[The Cattle Ranch][$slavesSeen += 1]]</strong><span class="yellow"> will sell at half price this week.</span>`;
+			schoolSale("The Cattle Ranch");
 		}
 		if (V.HA.schoolSale !== 0) {
-			r += `<br><span class="yellow">For your first purchase, </span><strong>[[The Hippolyta Academy][$slavesSeen += 1]]</strong><span class="yellow"> will sell at half price this week.</span>`;
+			schoolSale("The Hippolyta Academy");
 		}
 	}
 	if (V.seeDicks !== 0) {
 		if (V.LDE.schoolSale !== 0) {
-			r += `<br><span class="yellow">For your first purchase, </span><strong>[[L'École des Enculées][$slavesSeen += 1]]</strong><span class="yellow"> will sell at half price this week.</span>`;
+			schoolSale("L'École des Enculées");
 		}
 		if (V.TGA.schoolSale !== 0) {
-			r += `<br><span class="yellow">For your first purchase, </span><strong>[[The Gymnasium-Academy][$slavesSeen += 1]]</strong><span class="yellow"> will sell at half price this week.</span>`;
+			schoolSale("The Gymnasium-Academy");
 		}
 		if (V.TFS.schoolSale !== 0) {
-			r += `<br><span class="yellow">For your first purchase, </span><strong>[[The Futanari Sisters][$slavesSeen += 1]]</strong><span class="yellow"> will sell at half price this week.</span>`;
+			schoolSale("The Futanari Sisters");
 		}
 	}
 	if (V.NUL.schoolSale !== 0) {
-		r += `<br><span class="yellow">For your first purchase, </span><strong>[[Nueva Universidad de Libertad][$slavesSeen += 1]]</strong><span class="yellow"> will sell at half price this week.</span>`;
+		schoolSale("Nueva Universidad de Libertad");
 	}
-	return r;
+	return fragment;
 };
-/* CLOSE MAIN */
diff --git a/src/js/slaveListing.js b/src/js/slaveListing.js
index 218f957b63a..7c85af96b40 100644
--- a/src/js/slaveListing.js
+++ b/src/js/slaveListing.js
@@ -992,7 +992,7 @@ App.UI.SlaveList.penthousePage = function() {
 	let r = '';
 
 	if (V.positionMainLinks >= 0) {
-		r += '<center>' + App.UI.View.MainLinks() + '</center><br>';
+		r += '<center>' + App.UI.DOM.includeDOM(App.UI.View.mainLinks(), "mainLinks") + '</center><br>';
 	}
 
 	if (V.sortSlavesMain) {
@@ -1043,7 +1043,7 @@ App.UI.SlaveList.penthousePage = function() {
 	}
 
 	if (V.positionMainLinks <= 0) {
-		r += '<br><center>' + App.UI.View.MainLinks() + '</center>';
+		r += '<br><center>' + App.UI.DOM.includeDOM(App.UI.View.mainLinks(), "mainLinks") + '</center>';
 	}
 
 	App.UI.tabbar.handlePreSelectedTab();
-- 
GitLab