No edit summary Tag: Manual revert |
No edit summary |
||
| Line 73: | Line 73: | ||
document.body.classList.remove('search-top', 'search-header'); | document.body.classList.remove('search-top', 'search-header'); | ||
document.body.classList.add('search-' + searchMode); | document.body.classList.add('search-' + searchMode); | ||
// Scroll to top in header mode (banner removal shifts content) | |||
if (searchMode === 'header') { | |||
window.scrollTo(0, 0); | |||
document.addEventListener('DOMContentLoaded', function() { | |||
window.scrollTo(0, 0); | |||
}); | |||
} | |||
// Create toggle button | // Create toggle button | ||
Revision as of 21:12, 15 February 2026
1 /* Any JavaScript here will be loaded for all users on every page load. */
2
3 /* ============================================================
4 THEME TOGGLE — Dark/Light mode switcher
5 Defaults to dark. Saves preference to localStorage.
6 ============================================================ */
7 (function() {
8 // Apply theme from localStorage BEFORE page renders (avoid flash)
9 var saved = localStorage.getItem('flatmmo-theme') || 'dark';
10 document.documentElement.className += ' ' + saved + '-theme';
11
12 // Apply search bar mode BEFORE page renders (avoid flash)
13 var searchMode = localStorage.getItem('flatmmo-search') || 'top';
14 document.documentElement.className += ' search-' + searchMode;
15
16 document.addEventListener('DOMContentLoaded', function() {
17 document.body.classList.add(saved + '-theme');
18 document.body.classList.add('search-' + searchMode);
19 });
20 })();
21
22 $(document).ready(function () {
23 console.log("loaded");
24
25 // --- Theme toggle button ---
26 (function() {
27 var currentTheme = localStorage.getItem('flatmmo-theme') || 'dark';
28
29 // Ensure body has the right class
30 document.body.classList.remove('dark-theme', 'light-theme');
31 document.body.classList.add(currentTheme + '-theme');
32
33 // Create toggle button
34 var btn = document.createElement('button');
35 btn.className = 'theme-toggle-btn';
36 btn.title = 'Toggle light/dark mode';
37 btn.textContent = currentTheme === 'dark' ? '☀️' : '🌙';
38
39 btn.addEventListener('click', function() {
40 var isDark = document.body.classList.contains('dark-theme');
41 var newTheme = isDark ? 'light' : 'dark';
42
43 document.body.classList.remove('dark-theme', 'light-theme');
44 document.body.classList.add(newTheme + '-theme');
45 document.documentElement.classList.remove('dark-theme', 'light-theme');
46 document.documentElement.classList.add(newTheme + '-theme');
47
48 localStorage.setItem('flatmmo-theme', newTheme);
49 btn.textContent = newTheme === 'dark' ? '☀️' : '🌙';
50 });
51
52 // Insert into Cosmos header (next to wiki buttons) or fallback to content area
53 var target = document.querySelector('.cosmos-header__wiki-buttons')
54 || document.querySelector('.cosmos-actions')
55 || document.querySelector('.wds-button-group')
56 || document.querySelector('#content');
57 if (target) {
58 if (target.id === 'content') {
59 // Fallback: put it at the top of content
60 target.insertBefore(btn, target.firstChild);
61 } else {
62 target.appendChild(btn);
63 }
64 }
65
66 })();
67
68 // --- Search bar toggle + compact header search bar ---
69 (function() {
70 var searchMode = localStorage.getItem('flatmmo-search') || 'top';
71
72 // Ensure body has the right class
73 document.body.classList.remove('search-top', 'search-header');
74 document.body.classList.add('search-' + searchMode);
75
76 // Scroll to top in header mode (banner removal shifts content)
77 if (searchMode === 'header') {
78 window.scrollTo(0, 0);
79 document.addEventListener('DOMContentLoaded', function() {
80 window.scrollTo(0, 0);
81 });
82 }
83
84 // Create toggle button
85 var searchToggle = document.createElement('button');
86 searchToggle.className = 'search-toggle-btn';
87 searchToggle.title = 'Toggle search bar position';
88 searchToggle.textContent = searchMode === 'top' ? '🔍' : '🔎';
89
90 searchToggle.addEventListener('click', function() {
91 var isTop = document.body.classList.contains('search-top');
92 var newMode = isTop ? 'header' : 'top';
93
94 document.body.classList.remove('search-top', 'search-header');
95 document.body.classList.add('search-' + newMode);
96 document.documentElement.classList.remove('search-top', 'search-header');
97 document.documentElement.classList.add('search-' + newMode);
98
99 localStorage.setItem('flatmmo-search', newMode);
100 searchToggle.textContent = newMode === 'top' ? '🔍' : '🔎';
101 });
102
103 // Create compact header search bar
104 var searchWrap = document.createElement('div');
105 searchWrap.className = 'header-search-wrap';
106
107 var searchInput = document.createElement('input');
108 searchInput.type = 'text';
109 searchInput.className = 'header-search-input';
110 searchInput.placeholder = 'Search wiki...';
111 searchInput.setAttribute('autocomplete', 'off');
112
113 var searchBtn = document.createElement('button');
114 searchBtn.className = 'header-search-btn';
115 searchBtn.innerHTML = '🔍';
116 searchBtn.title = 'Search';
117
118 function doSearch() {
119 var q = searchInput.value.trim();
120 if (q) {
121 window.location.href = mw.util.getUrl('Special:Search') + '?search=' + encodeURIComponent(q);
122 }
123 }
124
125 searchBtn.addEventListener('click', doSearch);
126 searchInput.addEventListener('keydown', function(e) {
127 if (e.key === 'Enter') doSearch();
128 });
129
130 searchWrap.appendChild(searchInput);
131 searchWrap.appendChild(searchBtn);
132
133 // Insert toggle button inline with other header buttons
134 var target = document.querySelector('.cosmos-header__wiki-buttons')
135 || document.querySelector('.cosmos-actions')
136 || document.querySelector('.wds-button-group')
137 || document.querySelector('#content');
138 if (target && target.id !== 'content') {
139 target.appendChild(searchToggle);
140 // Make target the positioning anchor, append search bar inside
141 target.style.position = 'relative';
142 target.appendChild(searchWrap);
143
144 // Relocate username from banner into header for header mode
145 var bannerUser = document.querySelector('.cosmos-userButton-label')
146 || document.querySelector('#p-personal-label');
147 var userName = bannerUser ? bannerUser.textContent.trim() : '';
148 if (userName) {
149 var userLink = document.createElement('a');
150 userLink.className = 'relocated-user';
151 userLink.href = mw.util.getUrl('User:' + userName);
152 userLink.title = userName;
153
154 var userIcon = document.createElement('span');
155 userIcon.className = 'relocated-user-icon';
156 userIcon.innerHTML = '👤';
157
158 var userText = document.createElement('span');
159 userText.className = 'relocated-user-name';
160 userText.textContent = userName;
161
162 userLink.appendChild(userIcon);
163 userLink.appendChild(userText);
164 target.appendChild(userLink);
165 }
166 }
167 })();
168
169 $.getScript(mw.util.getUrl("MediaWiki:ProfileTags.js") + "?action=raw&ctype=text/javascript");
170 if (document.getElementById("interactiveMap")) {
171 console.log("map loaded")
172 $.getScript(mw.util.getUrl("MediaWiki:InteractiveMap/Objects.js") + "?action=raw&ctype=text/javascript", function() {
173 $.getScript(mw.util.getUrl("MediaWiki:InteractiveMap/NPCs.js") + "?action=raw&ctype=text/javascript", function() {
174 $.getScript(mw.util.getUrl("MediaWiki:InteractiveMap/Maps.js") + "?action=raw&ctype=text/javascript", function() {
175 $.getScript(mw.util.getUrl("MediaWiki:InteractiveMap.js") + "?action=raw&ctype=text/javascript", function() {
176 });
177 });
178 });
179 });
180 }
181
182 if (document.getElementById("wardrobe")) {
183 $.getScript(mw.util.getUrl("MediaWiki:Wardrobe.js") + "?action=raw&ctype=text/javascript");
184 console.log("wardrobe loaded")
185 }
186
187 if (document.getElementById("mapEditor")) {
188 $.getScript("https://cdn.jsdelivr.net/npm/interactjs/dist/interact.min.js", function() {
189 $.getScript(mw.util.getUrl("MediaWiki:InteractiveMap/Objects.js") + "?action=raw&ctype=text/javascript", function() {
190 $.getScript(mw.util.getUrl("MediaWiki:InteractiveMap/NPCs.js") + "?action=raw&ctype=text/javascript", function() {
191 $.getScript(mw.util.getUrl("MediaWiki:InteractiveMap/Maps.js") + "?action=raw&ctype=text/javascript", function() {
192 $.getScript(mw.util.getUrl("MediaWiki:MapEditor.js") + "?action=raw&ctype=text/javascript", function() {
193 });
194 });
195 });
196 });
197 });
198 }
199 if (document.querySelector(".code")) {
200 $.getScript("../custom/highlight.min.js", ()=>{
201 document.querySelectorAll(".code").forEach(el=>hljs.highlightElement(el))
202 console.log('Code highlighted');
203 });
204 }
205
206 if (document.querySelector('[class*="Tracker"]') && !document.querySelector('[class*="page-MediaWiki"]')) {
207 $.getScript(mw.util.getUrl("MediaWiki:Trackers.js") + "?action=raw&ctype=text/javascript");
208 console.log("Tracker loaded");
209 }
210
211 if (document.getElementById("enemiesDB")) {
212 $.getScript(mw.util.getUrl("MediaWiki:Update_DB.js") + "?action=raw&ctype=text/javascript");
213 console.log("DB Updater Loaded")
214 }
215 function hitChance(accuracy, defence) {
216 accuracy = parseInt(accuracy);
217 defence = parseInt(defence);
218 let hitChance = 0;
219 if(accuracy >= defence) {
220 hitChance = 1;
221 } else {
222 hitChance = 1 / (1 + defence - accuracy)
223 }
224 return (hitChance * 100).toFixed(2);
225 }
226 if (document.querySelector('.hitChance')) {
227 document.querySelectorAll(".hitChance").forEach(el => {
228 let [acc, def] = el.innerText.split(",")
229 el.innerText = "";
230 const accSpan = document.createElement("span");
231 const defSpan = document.createElement("span");
232 const hitSpan = document.createElement("span");
233 const accInput = document.createElement("input");
234 const defInput = document.createElement("input");
235 const hitValueSpan = document.createElement("span");
236
237 accSpan.innerText = "Accuracy:";
238 defSpan.innerText = "Defence:";
239 hitSpan.innerText = "Hit Chance:";
240
241 accInput.type = "number";
242 defInput.type = "number";
243 accInput.min = 0;
244 defInput.min = 0;
245 if(acc !== "0") {
246 accInput.disabled = true;
247 }
248 if(def !== "0") {
249 defInput.disabled = true
250 }
251 def = def < 0 ? 0 : def;
252 acc = acc < 0 ? 0 : acc;
253 accInput.defaultValue = acc;
254 defInput.defaultValue = def;
255 accInput.onchange = function(){
256 hitValueSpan.innerText = hitChance(accInput.value, defInput.value) + "%";
257 }
258 defInput.onchange = function(){
259 hitValueSpan.innerText = hitChance(accInput.value, defInput.value) + "%";
260 }
261 el.append(accSpan, accInput, defSpan, defInput, hitSpan, hitValueSpan);
262 hitValueSpan.innerText = hitChance(accInput.value, defInput.value) + "%";
263 })
264 }
265
266 });
