mudlet-map-browser-script 0.0.14 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js DELETED
@@ -1,917 +0,0 @@
1
- import Translator from "@andreasremdt/simple-translator";
2
- import bootstrap from "bootstrap";
3
- import {MapReader, Settings, Renderer} from "mudlet-map-renderer";
4
- import {Preview} from "./preview";
5
- import {downloadTags, downloadVersion} from "./versions";
6
- import convert from "color-convert";
7
-
8
- const rainbow = ["#CC99C9", "#9EC1CF", "#9EE09E", "#FDFD97", "#FEB144", "#FF6663"];
9
- let pathPick = 0;
10
-
11
- const defaultLanguage = document.querySelector("html").getAttribute("lang") ?? "pl";
12
-
13
- var translator = new Translator({
14
- defaultLanguage: defaultLanguage,
15
- detectLanguage: false,
16
- selector: "[data-i18n]",
17
- debug: false,
18
- registerGlobally: "__",
19
- persist: true,
20
- persistKey: "preferred_language",
21
- filesLocation: "i18n",
22
- });
23
- window.translator = translator;
24
-
25
- if (location.hostname !== "") {
26
- translator
27
- .fetch([defaultLanguage], false)
28
- .then(json => {
29
- let defaultLanguage = {};
30
- document.querySelectorAll("[data-i18n]").forEach(item => {
31
- defaultLanguage[item.getAttribute("data-i18n")] = item.innerHTML;
32
- });
33
- translator.add(defaultLanguage, {...defaultLanguage, ...json});
34
- })
35
- .catch(e => console.log(`Cannot fetch translations. ${e.message}`));
36
-
37
- translator
38
- .fetch(["en"])
39
- .then(() => {
40
- translator.translatePageTo();
41
- })
42
- .catch(e => console.log(`Cannot fetch translations. ${e.message}`));
43
- } else if (typeof translations !== "undefined") {
44
- let defaultLanguage = {};
45
- document.querySelectorAll("[data-i18n]").forEach(item => {
46
- defaultLanguage[item.getAttribute("data-i18n")] = item.innerHTML;
47
- });
48
- translator.add("pl", {...defaultLanguage, ...translations.pl});
49
- translator.add("en", translations.en);
50
- }
51
-
52
- const urlSearchParams = new URLSearchParams(window.location.search);
53
- const params = Object.fromEntries(urlSearchParams.entries());
54
- const url = window.location.origin + window.location.pathname;
55
-
56
- const svgToDataURL = svgStr => {
57
- const encoded = encodeURIComponent(svgStr).replace(/'/g, "%27").replace(/"/g, "%22");
58
-
59
- const header = "data:image/svg+xml,";
60
- const dataUrl = header + encoded;
61
-
62
- return dataUrl;
63
- };
64
-
65
- import {downloadNpc, findNpc} from "./npc";
66
- let roomNpc = {};
67
- downloadNpc().then(value => (roomNpc = value));
68
-
69
- let position = localStorage.getItem("position");
70
- if (position) {
71
- position = JSON.parse(position);
72
- }
73
- class PageControls {
74
- constructor(reader) {
75
- this.map = document.querySelector("#map");
76
- this.map.addEventListener("roomSelected", event => this.selectRoom(event.detail));
77
- this.map.addEventListener("roomDeselected", () => this.deselectRoom());
78
- this.map.addEventListener("zoom", event => this.adjustZoomBar(event.detail));
79
- this.map.addEventListener("zoom", event => (this.zoom = event.detail.zoom));
80
- this.map.addEventListener("zoom", event => this.preview.update());
81
- this.map.addEventListener("drag", event => this.preview.update());
82
- this.map.addEventListener("goToArea", event =>
83
- setTimeout(() => {
84
- if (event.detail.id) {
85
- this.findRoom(event.detail.id);
86
- }
87
- })
88
- );
89
- this.reader = reader;
90
- this.select = document.querySelector("#area");
91
- this.infoBox = document.querySelector(".info-box");
92
- this.levels = document.querySelector(".levels");
93
- this.saveImageButton = document.querySelector(".save-image");
94
- this.saveSvgImageButton = document.querySelector(".save-image-svg");
95
- this.copyImageButton = document.querySelector(".copy-image");
96
- this.zoomButtons = document.querySelectorAll(".zoom-controls .btn");
97
- this.toastContainer = document.querySelector(".toast");
98
- this.searchModal = document.querySelector("#search");
99
- this.search = document.querySelector(".search-form");
100
- this.findPathForm = document.querySelector(".findpath-form");
101
- this.findPathModal = document.querySelector("#findpath");
102
- this.helpModal = document.querySelector("#help");
103
- this.zoomBar = document.querySelector(".progress-container");
104
- this.settingsModal = document.querySelector("#settings");
105
- this.settingsForm = document.querySelector("#settings form");
106
- this.resetSettingsButton = document.querySelector("#settings button[type='reset']");
107
- this.versions = document.querySelector("#versions");
108
- this.releaseDescription = document.querySelector(".release-description");
109
- this.settings = new Settings();
110
- this.preview = new Preview(this.map, this);
111
- this.versionBadge = document.querySelector(".version-number");
112
- this.languageSelector = document.querySelector(".lang-dropdown");
113
- this.currentLanguageFlag = document.querySelector(".current-language-flag");
114
- this.pathBox = document.querySelector(".path-box ul");
115
- this.areaModal = document.getElementById("area-info")
116
- this.zIndex = 0;
117
- this.settings.optimizeDrag = true;
118
- this.settings.preview = true;
119
- let loaded = localStorage.getItem("settings");
120
- if (loaded) {
121
- Object.assign(this.settings, JSON.parse(loaded));
122
- }
123
-
124
- if (this.versions) {
125
- this.versions.addEventListener("change", event => {
126
- this.replaceVersion(event.target.value);
127
- this.releaseDescription.innerHTML = event.target.selectedOptions[0].getAttribute("data-description");
128
- bootstrap.Modal.getInstance(this.helpModal).hide();
129
- });
130
-
131
- this.helpModal.addEventListener("shown.bs.modal", () => {
132
- if (this.versions.children.length == 0) {
133
- downloadTags(this.versions.getAttribute("data-tags")).then(tags => {
134
- tags.forEach(tag => {
135
- let option = document.createElement("option");
136
- option.setAttribute("value", tag.tag_name);
137
- option.setAttribute("data-description", tag.body.replaceAll("\n\n", "\n"));
138
- option.innerHTML = tag.tag_name;
139
- this.versions.append(option);
140
- });
141
- this.releaseDescription.innerHTML = this.versions.firstChild.getAttribute("data-description");
142
- });
143
- }
144
- });
145
- }
146
-
147
- this.saveImageButton?.addEventListener("click", () => this.saveImage());
148
- this.saveSvgImageButton?.addEventListener("click", event => {
149
- event.preventDefault();
150
- this.downloadImage();
151
- });
152
- this.copyImageButton?.addEventListener("click", () => this.copyImage());
153
-
154
- this.zoomButtons.forEach(item =>
155
- item.addEventListener("click", event => {
156
- let delta = parseFloat(event.currentTarget.getAttribute("data-factor"));
157
- this.renderer.controls.deltaZoom(delta);
158
- })
159
- );
160
-
161
- this.search.addEventListener("submit", event => {
162
- event.preventDefault();
163
- this.submitSearch(event);
164
- });
165
-
166
- this.findPathForm?.addEventListener("submit", event => {
167
- event.preventDefault();
168
- this.submitPathFind(event);
169
- });
170
-
171
- this.findPathModal?.addEventListener("shown.bs.modal", () => {
172
- this.findPathModal.querySelector("input").focus();
173
- });
174
-
175
- this.searchModal.addEventListener("shown.bs.modal", () => {
176
- this.searchModal.querySelector("input").focus();
177
- });
178
-
179
- this.settingsModal.addEventListener("show.bs.modal", () => {
180
- this.populateSettings(this.settings);
181
- });
182
-
183
- this.settingsModal.addEventListener("shown.bs.modal", () => {
184
- this.settingsModal.querySelector("input").focus();
185
- });
186
-
187
- this.settingsForm.addEventListener("submit", event => {
188
- event.preventDefault();
189
- this.handleSaveSettings();
190
- });
191
-
192
- this.resetSettingsButton.addEventListener("click", event => {
193
- event.preventDefault();
194
- this.resetSettings();
195
- });
196
-
197
- this.areaModal?.addEventListener("show.bs.modal", () => {
198
- this.populateAreaInfo(this.areaId, this.zIndex);
199
- })
200
-
201
- window.addEventListener("resize", () => {
202
- this.render();
203
- });
204
-
205
- this.translatePage();
206
- this.languageSelector.querySelectorAll("a").forEach(element => {
207
- element.addEventListener("click", event => {
208
- event.preventDefault();
209
- this.translatePage(element.getAttribute("data-lang"));
210
- });
211
- });
212
-
213
- this.paths = {};
214
-
215
- this.renderer = new Renderer(this.map, this.reader, this.reader.getColors(), this.settings);
216
- }
217
-
218
- init() {
219
- // Check if version parameter is present
220
- if (params.version && this.versions) {
221
- this.replaceVersion(params.version);
222
- history.replaceState(null, null, url);
223
- return;
224
- }
225
-
226
- let area = this.reader.getAreas()[0].areaId;
227
- let zIndex = 0;
228
- if (params.loc) {
229
- this.findRoom(params.loc);
230
- history.replaceState(null, null, url);
231
- } else {
232
- if (params.area) {
233
- area = params.area;
234
- history.replaceState(null, null, url);
235
- } else if (position !== null && position.area) {
236
- area = position.area;
237
- zIndex = position.zIndex;
238
- }
239
- this.renderArea(area, zIndex);
240
- }
241
- }
242
-
243
- handleSaveSettings() {
244
- let inputs = this.settingsModal.querySelectorAll("input");
245
-
246
- let formData = {};
247
- inputs.forEach(element => {
248
- let name = element.getAttribute("name");
249
- let type = element.getAttribute("type");
250
- if (type === "checkbox") {
251
- formData[name] = element.checked;
252
- } else if (type === "number") {
253
- formData[name] = parseInt(element.value);
254
- } else {
255
- formData[name] = element.value;
256
- }
257
- });
258
-
259
- Object.assign(this.settings, formData);
260
-
261
- this.showToast(translator.translateForKey("settings-saved", translator.currentLanguage));
262
- bootstrap.Modal.getInstance(this.settingsModal).hide();
263
- this.saveSettings();
264
- this.render(true);
265
- }
266
-
267
- saveSettings() {
268
- localStorage.setItem("settings", JSON.stringify(this.settings));
269
- }
270
-
271
- render(force) {
272
- return this.renderArea(this.select.value, this.zIndex, force);
273
- }
274
-
275
- renderArea(areaId, zIndex, force) {
276
- return new Promise((resolve, reject) => {
277
- if (this.areaId !== areaId || this.zIndex !== zIndex || force) {
278
- this.map.addEventListener(
279
- "renderComplete",
280
- (event, renderer) => {
281
- this.preview.init(event.detail.controls).then(() => resolve());
282
- },
283
- {once: true}
284
- );
285
- this.areaId = areaId;
286
- this.zIndex = zIndex;
287
-
288
- localStorage.setItem("position", JSON.stringify({area: areaId, zIndex: zIndex}));
289
- document.querySelector("body").style.background = this.settings.mapBackground;
290
- let area = this.reader.getArea(areaId, zIndex);
291
- if (this.renderer) {
292
- this.renderer.clear();
293
- }
294
- this.renderer.renderArea(area)
295
- this.select.value = areaId;
296
- this.populateLevelButtons(area.getLevels(), zIndex);
297
- this.hideRoomInfo();
298
-
299
- Object.entries(this.paths).forEach(([key, group]) => {
300
- group.remove();
301
- let [from, to] = key.split("#");
302
- this.findPath(from, to);
303
- });
304
-
305
- this.renderer.clearHighlight();
306
- if (this.settings.keepZoomLevel && this.zoom) {
307
- this.renderer.controls.setZoom(this.zoom);
308
- }
309
- } else {
310
- resolve();
311
- }
312
- });
313
- }
314
-
315
- genericSetup() {
316
- document.querySelectorAll(".btn").forEach(element => element.addEventListener("click", () => element.blur()));
317
- }
318
-
319
- populateLevelButtons(levelsSet, zIndex) {
320
- this.levels.innerHTML = "";
321
- if (levelsSet.size <= 1) {
322
- return;
323
- }
324
- let levelsSorted = Array.from(levelsSet).sort(function (a, b) {
325
- return a - b;
326
- });
327
-
328
- if (levelsSorted.length > 10) {
329
- let container = document.createElement("div");
330
- container.classList.add("dropdown");
331
- let button = document.createElement("button");
332
- button.classList.add("btn", "btn-secondary", "dropdown-toggle");
333
- button.setAttribute("type", "button");
334
- button.setAttribute("data-bs-toggle", "dropdown");
335
- button.append(document.createTextNode(zIndex));
336
- let menu = document.createElement("div");
337
- menu.classList.add("dropdown-menu");
338
- container.append(button);
339
- container.append(menu);
340
- for (let level of levelsSorted) {
341
- let link = document.createElement("a");
342
- link.classList.add("dropdown-item", "btn-level");
343
- link.setAttribute("href", "#");
344
- link.setAttribute("data-level", level);
345
- link.append(document.createTextNode(level));
346
- menu.append(link);
347
- }
348
- this.levels.append(container);
349
- } else {
350
- for (let level of levelsSorted) {
351
- let button = document.createElement("button");
352
- button.setAttribute("type", "button");
353
- button.setAttribute("data-level", level);
354
- button.classList.add("btn", "btn-level");
355
- if (level === zIndex) {
356
- button.classList.add("btn-primary");
357
- } else {
358
- button.classList.add("btn-secondary");
359
- }
360
- button.append(document.createTextNode(level));
361
- this.levels.append(button);
362
- }
363
- }
364
- this.levels.querySelectorAll(".btn-level").forEach(item => {
365
- item.addEventListener("click", event => {
366
- event.preventDefault();
367
- let zIndex = parseInt(event.target.getAttribute("data-level"));
368
- this.renderArea(this.select.value, zIndex);
369
- });
370
- });
371
- }
372
-
373
- populateAreaInfo(areaId, zIndex) {
374
- let area = this.reader.getArea(areaId, zIndex);
375
- this.areaModal.querySelector(".area-name").innerHTML = `${area.areaName} (id: ${area.areaId})`;
376
- this.areaModal.querySelector(".area-room-count").innerHTML = Object.keys(area.rooms).length;
377
- let areaExits = this.areaModal.querySelector(".area-exits");
378
- areaExits.innerHTML = ""
379
- Object.values(area.rooms).flatMap(room => this.getAreaExits(room)).forEach(([id, targetId]) => {
380
- let targetArea = this.reader.getAreaByRoomId(targetId)
381
- let li = document.createElement("li")
382
- let roomLink = document.createElement("a")
383
- roomLink.setAttribute("href", "#")
384
- roomLink.setAttribute("data-room", id)
385
- roomLink.appendChild(document.createTextNode(id))
386
- roomLink.addEventListener("click", event => {
387
- event.preventDefault();
388
- this.findRoom(parseInt(event.currentTarget.getAttribute("data-room")));
389
- });
390
- let arrow = document.createTextNode(" -> ")
391
- let targetLink = document.createElement("a")
392
- targetLink.setAttribute("href", "#")
393
- targetLink.setAttribute("data-room", targetId)
394
- targetLink.appendChild(document.createTextNode(`${targetId} (${targetArea.areaName})`))
395
- targetLink.addEventListener("click", event => {
396
- event.preventDefault();
397
- this.findRoom(parseInt(event.currentTarget.getAttribute("data-room")));
398
- });
399
- li.append(roomLink, arrow, targetLink)
400
- areaExits.appendChild(li);
401
- })
402
- }
403
-
404
- getAreaExits(room) {
405
- let exits = [];
406
- Object.values(room.exits).filter(target => this.isExitTarget(target)).forEach(exitId => exits.push([room.id, exitId]))
407
- Object.values(room.specialExits).filter(target => this.isExitTarget(target)).forEach(exitId => exits.push([room.id, exitId]))
408
- return exits
409
- }
410
-
411
- isExitTarget(destinationRoom) {
412
- let destRoom = this.reader.getRoomById(destinationRoom);
413
- return parseInt(destRoom.areaId) !== this.renderer.area.areaId;
414
- }
415
-
416
- populateSelectBox() {
417
- this.select.querySelectorAll("option").forEach(item => item.remove());
418
- this.reader
419
- .getAreas()
420
- .filter(area => area.rooms.length > 0 && area.areaName !== undefined && area.areaName !== "")
421
- .sort((a, b) => {
422
- var nameA = a.areaName.toLowerCase(),
423
- nameB = b.areaName.toLowerCase();
424
- if (nameA < nameB) return -1;
425
- if (nameA > nameB) return 1;
426
- return 0;
427
- })
428
- .forEach((areaElement, index) => {
429
- if (!areaElement.rooms.length) {
430
- return;
431
- }
432
- this.select.append(new Option(areaElement.areaName, areaElement.areaId));
433
- });
434
- this.select.addEventListener("change", event => {
435
- this.renderArea(event.target.value, 0);
436
- });
437
- }
438
-
439
- submitSearch() {
440
- bootstrap.Modal.getInstance(this.searchModal).hide();
441
- let inputs = this.search.querySelectorAll("input");
442
-
443
- let formData = {};
444
- inputs.forEach(element => {
445
- formData[element.name] = element.value;
446
- element.value = "";
447
- });
448
-
449
- if (formData.roomId !== undefined) {
450
- let roomId = formData.roomId.split(",");
451
- if (isNaN(roomId[0])) {
452
- roomId = findNpc(roomId);
453
- }
454
- this.findRooms(roomId);
455
- }
456
- }
457
-
458
- submitPathFind() {
459
- bootstrap.Modal.getInstance(this.findPathModal).hide();
460
- let inputs = this.findPathForm.querySelectorAll("input");
461
-
462
- let formData = {};
463
- inputs.forEach(element => {
464
- formData[element.name] = element.value;
465
- element.value = "";
466
- });
467
- if (this.findPath(formData["start-loc"], formData["end-loc"])) {
468
- this.findRoom(formData["start-loc"]);
469
- }
470
- }
471
-
472
- findRoom(id) {
473
- if (!id) {
474
- return;
475
- }
476
- let area = this.reader.getAreaByRoomId(id);
477
- if (area !== undefined) {
478
- this.renderArea(area.areaId, area.zIndex).then(() => {
479
- this.renderer.controls.setZoom(1);
480
- this.renderer.controls.centerRoom(id);
481
- });
482
- } else {
483
- this.showToast(translator.translateForKey("location-not-found", translator.currentLanguage));
484
- }
485
- }
486
-
487
- findRooms(rooms) {
488
- let area = this.reader.getAreaByRoomId(rooms[0]);
489
- if (area !== undefined) {
490
- this.renderArea(area.areaId, area.zIndex).then(() => {
491
- this.renderer.controls.centerRoom(rooms[0]);
492
- this.renderer.controls.setZoom(1);
493
- this.renderer.clearHighlight();
494
- rooms.forEach(room => {
495
- this.renderer.renderHighlight(room);
496
- });
497
- //this.renderer.controls.centerOnItem(this.renderer.highlights);
498
- });
499
- } else {
500
- this.showToast(translator.translateForKey("location-not-found", translator.currentLanguage));
501
- }
502
- }
503
-
504
- findPath(from, to) {
505
- let key = `${from}#${to}`;
506
- let pathColor = this.pathBox.querySelector(`[data-path-key='${key}'] input[type='color']`)?.value ?? rainbow[pathPick++ % rainbow.length];
507
- this.paths[key] = this.renderer.controls.renderPath(
508
- from,
509
- to,
510
- convert.hex.rgb(pathColor).map(item => item / 255)
511
- );
512
- if (!this.paths[key]) {
513
- delete this.paths[key];
514
- this.showToast(translator.translateForKey("no-path", translator.currentLanguage));
515
- pathPick--;
516
- return;
517
- }
518
- if (!this.pathBox.querySelector(`[data-path-key='${key}']`)) {
519
- let pathSelector = document.createElement("li");
520
- pathSelector.classList.add("list-group-item", "d-inline-flex", "align-items-center", "position-relative");
521
- pathSelector.setAttribute("data-path-key", key);
522
-
523
- let color = document.createElement("input");
524
- color.setAttribute("type", "color");
525
- color.classList.add("small-color", "me-2");
526
- color.value = pathColor;
527
- color.addEventListener("input", event => {
528
- this.paths[key].strokeColor = event.target.value;
529
- });
530
- pathSelector.appendChild(color);
531
-
532
- pathSelector.appendChild(document.createTextNode(`${from} -> ${to}`));
533
-
534
- let deletePath = document.createElement("span");
535
- deletePath.classList.add("badge", "bg-secondary", "position-absolute", "end-0", "me-2");
536
- deletePath.appendChild(document.createTextNode(translator.translateForKey("delete", translator.currentLanguage)));
537
- deletePath.onclick = () => {
538
- this.paths[key].remove();
539
- delete this.paths[key];
540
- pathSelector.remove();
541
-
542
- if (Object.keys(this.paths).length === 0) {
543
- this.pathBox.parentNode.classList.add("invisible");
544
- }
545
- };
546
- pathSelector.appendChild(deletePath);
547
- this.pathBox.appendChild(pathSelector);
548
- this.pathBox.parentNode.classList.remove("invisible");
549
- return true;
550
- }
551
- }
552
-
553
- adjustZoomBar(view) {
554
- let percentage = (view.zoom - view.minZoom) / (10 - view.minZoom);
555
-
556
- this.zoomBar.querySelector(".progress-bar").style.width = percentage * 100 + "%";
557
- if (!this.zoomBar.classList.contains("visible")) {
558
- this.zoomBar.classList.add("visible");
559
- this.zoomBar.classList.remove("hidden");
560
- this.progressTimeout = setTimeout(() => {
561
- this.zoomBar.classList.add("hidden");
562
- this.zoomBar.classList.remove("visible");
563
- }, 3000);
564
- } else {
565
- if (this.progressTimeout !== undefined) {
566
- clearTimeout(this.progressTimeout);
567
- this.progressTimeout = undefined;
568
- }
569
- this.progressTimeout = setTimeout(() => {
570
- this.zoomBar.classList.add("hidden");
571
- this.zoomBar.classList.remove("visible");
572
- }, 3000);
573
- }
574
- }
575
-
576
- selectRoom(room) {
577
- this.showRoomInfo(room);
578
- }
579
-
580
- deselectRoom() {
581
- this.hideRoomInfo();
582
- }
583
-
584
- showRoomInfo(room) {
585
- let bgColor = this.reader.getColors()[room.env] ?? [114, 1, 0]
586
- this.infoBox.style.border = `2px solid rgba(${bgColor[0]}, ${bgColor[1]}, ${bgColor[2]}, 0.5)`
587
- this.infoBox.style.display = "initial";
588
- this.infoBox.querySelector(".room-id").innerHTML = room.id;
589
- this.infoBox.querySelector(".room-link").setAttribute("href", `${url}?loc=${room.id}`);
590
- this.infoBox.querySelector(".room-name").innerHTML = room.name;
591
- this.infoBox.querySelector(".room-env").innerHTML = room.env;
592
- this.infoBox.querySelector(".coord-x").innerHTML = room.x;
593
- this.infoBox.querySelector(".coord-y").innerHTML = room.y;
594
- this.infoBox.querySelector(".coord-z").innerHTML = room.z;
595
- this.infoBox.querySelector(".room-hash").innerHTML = "";
596
- this.infoBox.querySelector(".room-hash").innerHTML = room.hash ?? "";
597
-
598
- this.infoExitsGroup(this.infoBox.querySelector(".exits"), room.exits);
599
- this.infoExitsGroup(this.infoBox.querySelector(".special"), room.specialExits);
600
-
601
- this.userDataGroup(this.infoBox.querySelector(".userData"), room.userData);
602
- this.npcDataGroup(this.infoBox.querySelector(".npc"), roomNpc[room.id] || {});
603
- }
604
-
605
- userDataGroup(container, userData) {
606
- let containerList = container.querySelector("ul");
607
- containerList.innerHTML = "";
608
- let show = false;
609
- for (let userDataKey in userData) {
610
- show = true;
611
- let dataElement = document.createElement("li");
612
- dataElement.classList = ["user-data"];
613
- let key = document.createElement("p");
614
- key.append(`${userDataKey}:`);
615
- let value = document.createElement("p");
616
- value.append(`${userData[userDataKey].replaceAll("\\n", "\n")}`)
617
- value.className = "value";
618
- dataElement.append(key, value)
619
- containerList.append(dataElement);
620
- }
621
- container.style.display = show ? "initial" : "none";
622
- }
623
-
624
- infoExitsGroup(container, exits) {
625
- let containerList = container.querySelector("ul");
626
- containerList.innerHTML = "";
627
- let show = false;
628
- for (let exit in exits) {
629
- show = true;
630
- containerList.append(this.infoExit(exit, exits[exit]));
631
- }
632
- container.style.display = show ? "initial" : "none";
633
- }
634
-
635
- npcDataGroup(container, npcs) {
636
- let containerList = container.querySelector("ul");
637
- containerList.innerHTML = "";
638
- let show = false;
639
- for (let npc in npcs) {
640
- show = true;
641
- let element = document.createElement("li");
642
- element.append(document.createTextNode(npcs[npc]));
643
- containerList.append(element);
644
- }
645
- container.style.display = show ? "initial" : "none";
646
- }
647
-
648
- infoExit(exit, id) {
649
- let exitElement = document.createElement("li");
650
-
651
- let exitDir = document.createElement("span");
652
- exitDir.setAttribute("data-i18n", exit);
653
- exitDir.innerHTML = this.translateDir(exit);
654
- exitElement.append(exitDir);
655
- exitElement.append(document.createTextNode(": "));
656
-
657
- let link = document.createElement("a");
658
- link.setAttribute("href", "#");
659
- link.setAttribute("data-room", id);
660
- link.innerHTML = id;
661
- link.addEventListener("click", event => {
662
- event.preventDefault();
663
- this.findRoom(parseInt(event.currentTarget.getAttribute("data-room")));
664
- });
665
- exitElement.append(link);
666
-
667
- let destRoom = this.reader.getRoomById(id);
668
- if (parseInt(destRoom.areaId) !== this.renderer.area.areaId) {
669
- let area = this.reader.getAreaProperties(destRoom.areaId);
670
- exitElement.append(document.createTextNode(" -> "));
671
- let areaLink = document.createElement("a");
672
- areaLink.setAttribute("href", "#");
673
- areaLink.setAttribute("data-room", destRoom.id);
674
- areaLink.innerHTML = area.areaName;
675
- areaLink.addEventListener("click", event => {
676
- event.preventDefault();
677
- this.findRoom(parseInt(event.currentTarget.getAttribute("data-room")));
678
- });
679
- exitElement.append(areaLink);
680
- }
681
-
682
- return exitElement;
683
- }
684
-
685
- showToast(text) {
686
- this.toastContainer.querySelector(".toast-body").innerHTML = text;
687
- bootstrap.Toast.getOrCreateInstance(this.toastContainer).show();
688
- }
689
-
690
- translateDir(dir) {
691
- return translator.translateForKey(dir) ?? dir;
692
- }
693
-
694
- translatePage(lang) {
695
- this.currentLanguageFlag.classList.remove(`flag-${translator.currentLanguage}`);
696
- if (lang) {
697
- translator.translatePageTo(lang);
698
- }
699
- this.currentLanguageFlag.classList.add(`flag-${translator.currentLanguage}`);
700
- }
701
-
702
- hideRoomInfo() {
703
- this.infoBox.style.display = "none";
704
- }
705
-
706
- populateSettings(settings) {
707
- for (let setting in settings) {
708
- let input = this.settingsModal.querySelector("#nav-map").querySelector("input[name='" + setting + "']");
709
- if (!input) {
710
- continue;
711
- }
712
- if (input.getAttribute("type") === "checkbox") {
713
- input.checked = settings[setting];
714
- } else if (input.getAttribute("type") === "color") {
715
- input.value = settings[setting].toCSS ? settings[setting].toCSS(true) : settings[setting];
716
- } else {
717
- input.value = settings[setting];
718
- }
719
- }
720
- }
721
-
722
- resetSettings() {
723
- let defaults = new Settings();
724
- defaults.preview = true;
725
- defaults.optimizeDrag = true;
726
- this.populateSettings(defaults);
727
- }
728
-
729
- saveImage() {
730
- let a = document.createElement("a");
731
- a.setAttribute("href", this.map.toDataURL());
732
- a.setAttribute("download", this.renderer.area.areaName + ".png");
733
- document.querySelector("body").append(a);
734
- a.click();
735
- a.remove();
736
- }
737
-
738
- downloadImage() {
739
- let a = document.createElement("a");
740
- a.setAttribute("href", svgToDataURL(this.renderer.exportSvg()));
741
- a.setAttribute("download", this.renderer.area.areaName + ".svg");
742
- document.querySelector("body").append(a);
743
- a.click();
744
- a.remove();
745
- }
746
-
747
- copyImage() {
748
- if (typeof ClipboardItem !== "undefined") {
749
- this.map.toBlob(blob => navigator.clipboard.write([new ClipboardItem({"image/png": blob})]));
750
- this.showToast(translator.translateForKey("copied", translator.currentLanguage));
751
- } else {
752
- this.showToast(translator.translateForKey("no-clipboard", translator.currentLanguage));
753
- }
754
- }
755
-
756
- move(x, y) {
757
- this.renderer.controls.move(x, y);
758
- this.preview.update()
759
- }
760
-
761
- goDirection(directionKey) {
762
- let fullDirection = dirsShortToLong(directionKey);
763
- if (this.renderer.controls.selected) {
764
- this.findRoom(this.renderer.controls.selected.exits[fullDirection]);
765
- }
766
- }
767
-
768
- registerKeyBoard() {
769
- let directionKeys = {
770
- Numpad1: "sw",
771
- Numpad2: "s",
772
- Numpad3: "se",
773
- Numpad4: "w",
774
- Numpad6: "e",
775
- Numpad7: "nw",
776
- Numpad8: "n",
777
- Numpad9: "ne",
778
- NumpadMultiply: "u",
779
- NumpadDivide: "d",
780
- };
781
-
782
- window.addEventListener("keydown", event => {
783
- if (this.settings.disableKeyBinds) {
784
- return;
785
- }
786
-
787
- if (event.code === "F1") {
788
- event.preventDefault();
789
- this.showHelp();
790
- }
791
-
792
- if (event.ctrlKey && event.code === "KeyF") {
793
- event.preventDefault();
794
- this.showSearch();
795
- }
796
- });
797
-
798
- window.addEventListener("resize", () => {
799
- this.render(true);
800
- });
801
-
802
- window.addEventListener("keydown", event => {
803
- if (document.querySelector("input:focus") || this.settings.disableKeyBinds) {
804
- return;
805
- }
806
-
807
- if (event.ctrlKey && event.code === "KeyS") {
808
- this.saveImage();
809
- event.preventDefault();
810
- }
811
-
812
- if (event.code === "Equal") {
813
- this.renderer.controls.deltaZoom(1.1);
814
- event.preventDefault();
815
- }
816
-
817
- if (event.code === "Minus") {
818
- this.renderer.controls.deltaZoom(0.9);
819
- event.preventDefault();
820
- }
821
-
822
- if (event.code === "ArrowUp") {
823
- this.move(0, -1);
824
- event.preventDefault();
825
- }
826
- if (event.code === "ArrowDown") {
827
- this.move(0, 1);
828
- event.preventDefault();
829
- }
830
- if (event.code === "ArrowLeft") {
831
- this.move(-1, 0);
832
- event.preventDefault();
833
- }
834
- if (event.code === "ArrowRight") {
835
- this.move(1, 0);
836
- event.preventDefault();
837
- }
838
-
839
- if (directionKeys.hasOwnProperty(event.code)) {
840
- this.goDirection(directionKeys[event.code]);
841
- event.preventDefault();
842
- }
843
- });
844
- }
845
-
846
- showHelp() {
847
- bootstrap.Modal.getOrCreateInstance(this.helpModal).show();
848
- }
849
-
850
- showSearch() {
851
- bootstrap.Modal.getOrCreateInstance(this.searchModal).show();
852
- }
853
-
854
- replaceVersion(tag) {
855
- downloadVersion(tag, this.versions.getAttribute("data-files")).then(data => {
856
- this.reader = new MapReader(data, colors);
857
- this.populateSelectBox();
858
-
859
- // Determine which area to render
860
- let area = this.reader.getAreas()[0].areaId;
861
- let zIndex = 0;
862
-
863
- if (params.loc) {
864
- this.findRoom(params.loc);
865
- } else if (params.area) {
866
- area = params.area;
867
- this.renderArea(area, zIndex);
868
- } else if (this.areaId !== undefined) {
869
- // If already initialized, use current area
870
- this.renderArea(this.areaId, this.zIndex, true).then(() => this.showToast(`Przeładowano wersję na ${tag}`));
871
- } else {
872
- // First initialization
873
- if (position !== null && position.area) {
874
- area = position.area;
875
- zIndex = position.zIndex;
876
- }
877
- this.renderArea(area, zIndex);
878
- }
879
-
880
- this.versionBadge.innerHTML = `v${tag}`;
881
- this.versionBadge.style.display = "initial";
882
- });
883
- }
884
- }
885
-
886
- let controls = new PageControls(new MapReader(mapData, colors));
887
- window.controls = controls;
888
- controls.genericSetup();
889
- controls.populateSelectBox();
890
- controls.init();
891
- controls.registerKeyBoard();
892
-
893
- let dirs = {
894
- north: "n",
895
- south: "s",
896
- east: "e",
897
- west: "w",
898
- northeast: "ne",
899
- northwest: "nw",
900
- southeast: "se",
901
- southwest: "sw",
902
- up: "u",
903
- down: "d",
904
- };
905
-
906
- function getKeyByValue(obj, val) {
907
- for (let k in obj) {
908
- if (obj.hasOwnProperty(k) && obj[k] === val) {
909
- return k;
910
- }
911
- }
912
- }
913
-
914
- function dirsShortToLong(dir) {
915
- let result = getKeyByValue(dirs, dir);
916
- return result !== undefined ? result : dir;
917
- }