1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
|
/**
* wikilinks.js
*
* Automatically turns known Star Citizen ship, weapon, armor, and tool names
* found in the page's text into hyperlinks pointing to starcitizen.tools.
*
* How it works:
* 1. `linkMap` defines each recognized term and its destination URL.
* 2. On DOMContentLoaded, a single regex is built from all terms, sorted
* longest-first so multi-word names (e.g. "Fury MX") take precedence
* over shorter overlapping ones (e.g. "Fury").
* 3. The document body's text nodes are walked and any matching term is
* replaced in place with an anchor element. Text already inside an
* existing <a> is skipped to avoid nested links.
*
* To add a new link, insert a `"Display Name": "https://..."` entry into
* `linkMap`.
*/
document.addEventListener("DOMContentLoaded", () => {
const linkMap = {
"A2 Hercules Starlifter":
"https://starcitizen.tools/A2_Hercules_Starlifter",
"Apollo Medivac": "https://starcitizen.tools/Apollo_Medivac",
Asgard: "https://starcitizen.tools/Asgard",
Carrack: "https://starcitizen.tools/Carrack",
Crucible: "https://starcitizen.tools/Crucible",
"Cutlass Red": "https://starcitizen.tools/Cutlass_Red",
Eclipse: "https://starcitizen.tools/Eclipse",
"Fury MX": "https://starcitizen.tools/Fury_MX",
Fury: "https://starcitizen.tools/Fury",
Hammerhead: "https://starcitizen.tools/Hammerhead",
Herald: "https://starcitizen.tools/Herald",
"Hull C": "https://starcitizen.tools/Hull_C",
"Hull E": "https://starcitizen.tools/Hull_E",
"Idris-K": "https://starcitizen.tools/Idris-K",
"Ironclad Assault": "https://starcitizen.tools/Ironclad_Assault",
Kraken: "https://starcitizen.tools/Kraken",
Legionnaire: "https://starcitizen.tools/Legionnaire",
Mole: "https://starcitizen.tools/Mole",
Nautilus: "https://starcitizen.tools/Nautilus",
Orion: "https://starcitizen.tools/Orion",
Perseus: "https://starcitizen.tools/Perseus",
Polaris: "https://starcitizen.tools/Polaris",
Prowler: "https://starcitizen.tools/Prowler",
Reclaimer: "https://starcitizen.tools/Reclaimer",
Retaliator: "https://starcitizen.tools/Retaliator",
Scorpius: "https://starcitizen.tools/Scorpius",
"Starfarer Gemini": "https://starcitizen.tools/Starfarer_Gemini",
"Terrapin Medic": "https://starcitizen.tools/Terrapin_Medic",
Tiburon: "https://starcitizen.tools/Tiburon",
Valkyrie: "https://starcitizen.tools/Valkyrie",
"Vanguard Sentinel": "https://starcitizen.tools/Vanguard_Sentinel",
"Arclight Pistol": "https://starcitizen.tools/Arclight_Pistol",
"Arden-SL Arms": "https://starcitizen.tools/Arden-SL_Arms",
"Arden-SL Core": "https://starcitizen.tools/Arden-SL_Core",
"Arden-SL Helmet": "https://starcitizen.tools/Arden-SL_Helmet",
"Arden-SL Legs": "https://starcitizen.tools/Arden-SL_Legs",
"Calico Arms Tactical": "https://starcitizen.tools/Calico_Arms_Tactical",
"Calico Core Tactical": "https://starcitizen.tools/Calico_Core_Tactical",
"Calico Helmet Tactical":
"https://starcitizen.tools/Calico_Helmet_Tactical",
"Calico Legs Tactical": "https://starcitizen.tools/Calico_Legs_Tactical",
"DustUp Arms Tactical": "https://starcitizen.tools/DustUp_Arms_Tactical",
"DustUp Core Tactical": "https://starcitizen.tools/DustUp_Core_Tactical",
"DustUp Helmet Tactical":
"https://starcitizen.tools/DustUp_Helmet_Tactical",
"DustUp Legs Tactical": "https://starcitizen.tools/DustUp_Legs_Tactical",
"Killshot Rifle": "https://starcitizen.tools/Killshot_Rifle",
"Morozov-SH Arms": "https://starcitizen.tools/Morozov-SH_Arms",
"Morozov-SH Core": "https://starcitizen.tools/Morozov-SH_Core",
"Morozov-SH Helmet": "https://starcitizen.tools/Morozov-SH_Helmet",
"Morozov-SH Legs": "https://starcitizen.tools/Morozov-SH_Legs",
"P6-LR Sniper Rifle": "https://starcitizen.tools/P6-LR_Sniper_Rifle",
"Pulverizer LMG": "https://starcitizen.tools/Pulverizer_LMG",
"S-38 Pistol": "https://starcitizen.tools/S-38_Pistol",
"Stoneskin Undersuit": "https://starcitizen.tools/Stoneskin_Undersuit",
"TripleDown Shotgun Pistol":
"https://starcitizen.tools/TripleDown_Shotgun_Pistol",
"Yubarev Pistol": "https://starcitizen.tools/Yubarev_Pistol",
"ADP-mk4 Arms": "https://starcitizen.tools/ADP-mk4_Arms",
"ADP-mk4 Core": "https://starcitizen.tools/ADP-mk4_Core",
"ADP-mk4 Helmet": "https://starcitizen.tools/ADP-mk4_Helmet",
"ADP-mk4 Legs": "https://starcitizen.tools/ADP-mk4_Legs",
"Tailwind Flight Helmet":
"https://starcitizen.tools/Tailwind_Flight_Helmet",
"Tailwind Flight Suit": "https://starcitizen.tools/Tailwind_Flight_Suit",
"Novikov Exploration Suit":
"https://starcitizen.tools/Novikov_Exploration_Suit",
"Novikov Helmet": "https://starcitizen.tools/Novikov_Helmet",
"APX Fire Extinguisher": "https://starcitizen.tools/APX_Fire_Extinguisher",
"Cambio SRT": "https://starcitizen.tools/Cambio_SRT",
"Pyro RYT Multi-Tool": "https://starcitizen.tools/Pyro_RYT_Multi-Tool",
"TruHold Tractor Beam Attachment":
"https://starcitizen.tools/TruHold_Tractor_Beam_Attachment",
};
// Build one regex from every term, longest first so multi-word names
// like "Fury MX" win over shorter ones like "Fury".
const escaped = Object.keys(linkMap)
.sort((a, b) => b.length - a.length)
.map((term) => term.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"));
const termPattern = new RegExp(`\\b(${escaped.join("|")})\\b`, "g");
// Collect text nodes up front, since we mutate the DOM as we go.
const walker = document.createTreeWalker(document.body, NodeFilter.SHOW_TEXT);
const textNodes = [];
while (walker.nextNode()) textNodes.push(walker.currentNode);
for (const node of textNodes) {
// Skip text that is already inside a link.
if (node.parentNode.closest("a")) continue;
const text = node.textContent;
const matches = [...text.matchAll(termPattern)];
if (matches.length === 0) continue;
// Rebuild the node as a mix of plain text and anchor elements.
const fragment = document.createDocumentFragment();
let cursor = 0;
for (const match of matches) {
const term = match[0];
fragment.append(text.slice(cursor, match.index));
const link = document.createElement("a");
link.href = linkMap[term];
link.textContent = term;
fragment.append(link);
cursor = match.index + term.length;
}
fragment.append(text.slice(cursor));
node.parentNode.replaceChild(fragment, node);
}
});
|