PageSourceSearch

https://www.comunbadia.it/system/statV.1789655742/Javascript/L3G0/location.l3g0.js

js comunbadia.it collected 2026-10-02 20:43:44 UTC 15,365 bytes, 398 lines download raw bytes

1/*
2Plugin: location.l3g0
3Author: Tobias Ratzberger (RIS GmbH)
4Written: 10.02.2022
5*/
6
7class DistanceCalcluation {
8    #clientLocationInstance;
9    #boundHandleLocationRequestInvoke;
10    #boundHandleLocationRequest;
11    #boundHandleLocationRequestSuccess;
12    #boundHandleLocationRequestError;
13
14    constructor() {
15        this.valueContainerSelector = arguments[1];
16
17        this.#boundHandleLocationRequestInvoke = this.#handleLocationRequestInvoke.bind(this);
18        this.#boundHandleLocationRequest = this.#handleLocationRequest.bind(this);
19        this.#boundHandleLocationRequestSuccess = this.#handleLocationRequestSuccess.bind(this);
20        this.#boundHandleLocationRequestError = this.#handleLocationRequestError.bind(this);
21
22        this.#clientLocationInstance = this.#getClientLocation({
23            enableHighAccuracy: false,
24            timeout: 60000,
25            maximumAge: 0
26        });
27
28        this.dataContainer = null;
29        this.valueContainer = null;
30        this.destLocData = null;
31
32        if (arguments[0] && arguments[0].nodeType === Node.ELEMENT_NODE) {
33            if (arguments[0].querySelector(this.valueContainerSelector)) {
34                this.dataContainer = arguments[0];
35                this.valueContainer = arguments[0].querySelector(this.valueContainerSelector);
36
37                this.destLocData = {
38                    lat: this.dataContainer.getAttribute("data-lat"),
39                    lon: this.dataContainer.getAttribute("data-lon")
40                }
41            } else {
42                console.error("You passed an invalid Element-Structure or an wrong Selector");
43            }
44        } else {
45            console.error("You passed an invalid Argument!");
46        }
47    }
48
49    init() {
50        document.addEventListener("location-request", this.#boundHandleLocationRequest);
51        document.addEventListener("location-request-success", this.#boundHandleLocationRequestSuccess);
52        document.addEventListener("location-request-error", this.#boundHandleLocationRequestError);
53
54        this.#clientLocationInstance.permission.then((permissionState) => {
55            if (permissionState == "granted") {
56                this.#clientLocationInstance.requestLocation().catch((error) => { console.debug(error) });
57            } else if (permissionState == "prompt") {
58                this.dataContainer.addEventListener("click", this.#boundHandleLocationRequestInvoke);
59                this.dataContainer.addEventListener("keydown", this.#boundHandleLocationRequestInvoke);
60            } else {
61                this.#destroy();
62            }
63        }).catch((error) => {
64            this.#destroy();
65
66            console.error("L3G0 Location: Error occoured while requesting permission for location.\n" + error.message);
67        });
68    }
69
70    //Method: Handles when user invoked manually
71    #handleLocationRequestInvoke(event) {
72        if (event.type == "keydown" && event.key != "Enter") {
73            return
74        }
75
76        this.#removeInvokeListener();
77        this.#clientLocationInstance.requestLocation().catch((error) => { console.debug(error) });
78    }
79
80    //Method: Handles location request
81    #handleLocationRequest(event) {
82        this.#removeLocationRequestListener();
83
84        this.#setLoader();
85    }
86
87    //Method: Handles successful location request. 
88    #handleLocationRequestSuccess(event) {
89        this.#removeInvokeListener();
90        this.#removeLocationRequestSuccessListener();
91        this.#removeLocationRequestErrorListener();
92
93        const clientLat = event.detail.coords.latitude;
94        const clientLon = event.detail.coords.longitude;
95
96        this.valueContainer.innerText = this.#formatBeeLine(this.#calcBeeLine(this.destLocData.lat, this.destLocData.lon, clientLat, clientLon));
97    }
98
99    //Mehtod: Handles error while requesting location. 
100    #handleLocationRequestError(event) {
101        this.#destroy();
102
103        console.error("L3G0 Location: Error occoured while requesting location.\n" + event.detail.message);
104    }
105
106    //Method: Initializes ClientLocationData Instance
107    #getClientLocation(options) {
108        return new ClientLocationData(options);
109    }
110
111    //Method: Sets Loader to valueContainer
112    #setLoader() {
113        this.valueContainer.innerHTML = "<span class='fad fa-spinner fa-spin' aria-hidden='true'></span>";
114    }
115
116    //Mehtod: Calculated As-The-Crow-Flies Line
117    #calcBeeLine(destLat, destLon, clientLat, clientLon) {
118        const earthRadiusKm = 6371;
119
120        const latDelta = this.#degreesToRadians(clientLat - destLat);
121        const lonDelta = this.#degreesToRadians(clientLon - destLon);
122
123        const destLatRad = this.#degreesToRadians(destLat);
124        const clientLatRad = this.#degreesToRadians(clientLat);
125
126        const $a = Math.sin(latDelta / 2) * Math.sin(latDelta / 2) + Math.sin(lonDelta / 2) * Math.sin(lonDelta / 2) * Math.cos(destLatRad) * Math.cos(clientLatRad);
127        const $b = 2 * Math.atan2(Math.sqrt($a), Math.sqrt(1 - $a));
128
129        const distance = earthRadiusKm * $b;
130
131        return distance;
132    }
133
134    //Method: Formatting As-The-Crow-Flies Line
135    #formatBeeLine(beeLine) {
136        let formattedBeeLine = beeLine;
137
138        if (formattedBeeLine < 0.1) {
139            formattedBeeLine = "< " + 0.1;
140        } else if (formattedBeeLine < 1) {
141            formattedBeeLine = formattedBeeLine.toFixed(2);
142        } else if (formattedBeeLine < 10) {
143            formattedBeeLine = formattedBeeLine.toFixed(1);
144        } else {
145            formattedBeeLine = Math.round(formattedBeeLine);
146        }
147
148        return formattedBeeLine += " km";
149    }
150
151    //Method: Converting Degree to Radian
152    #degreesToRadians(val) {
153        return val * Math.PI / 180;
154    }
155
156    //Method: Removes all Eventlisteners and removes dataContainer from DOM 
157    #destroy() {
158        this.#removeInvokeListener();
159        this.#removeLocationRequestListener();
160        this.#removeLocationRequestSuccessListener();
161        this.#removeLocationRequestErrorListener();
162        this.#removeEl();
163    }
164
165    //Method: Remove DataContainer from DOM
166    #removeEl() {
167        this.dataContainer.remove();
168    }
169
170    //Method Group: Removing diverse eventListener
171    #removeInvokeListener() {
172        this.dataContainer.removeEventListener("click", this.#boundHandleLocationRequestInvoke);
173        this.dataContainer.removeEventListener("keydown", this.#boundHandleLocationRequestInvoke);
174    }
175
176    #removeLocationRequestListener() {
177        document.removeEventListener("location-request", this.#boundHandleLocationRequest);
178    }
179
180    #removeLocationRequestSuccessListener() {
181        document.removeEventListener("location-request-success", this.#boundHandleLocationRequestSuccess);
182    }
183
184    #removeLocationRequestErrorListener() {
185        document.removeEventListener("location-request-error", this.#boundHandleLocationRequestError);
186    }
187}
188
189class DistanceOrder {
190    #invokedOrderChange;
191    #clientLocationInstance;
192    #coordRegex;
193    #transferValueToElHasValidCoordinates;
194    #boundHandleLocationRequestInvoke;
195    #boundHandleLocationRequest;
196    #boundHandleLocationRequestSuccess;
197    #boundHandleLocationRequestError;
198
199    constructor($optionElement, $querySelector_transferValueToEl, $querySelector_filterContainer, $instantSubmit = true) {
200        this.instantSubmit = $instantSubmit;
201        this.#invokedOrderChange = false;
202
203        this.#coordRegex = new RegExp(/^\d+\.?\d*,\d+\.?\d*$/);
204        this.#boundHandleLocationRequestInvoke = this.#handleLocationRequestInvoke.bind(this);
205        this.#boundHandleLocationRequest = this.#handleLocationRequest.bind(this);
206        this.#boundHandleLocationRequestSuccess = this.#handleLocationRequestSuccess.bind(this);
207        this.#boundHandleLocationRequestError = this.#handleLocationRequestError.bind(this);
208
209        this.#clientLocationInstance = this.#getClientLocation({
210            enableHighAccuracy: false,
211            timeout: 60000,
212            maximumAge: 0
213        });
214
215        this.optionElement = null;
216        this.selectElement = null;
217        this.optionElementValueId = null;
218        this.#transferValueToElHasValidCoordinates = false;
219
220        //Has to be in same filterContainer as optionEl
221        this.transferValueToEl = null;
222
223        if ($optionElement && $optionElement.nodeType === Node.ELEMENT_NODE && $optionElement.tagName == "OPTION") {
224            if ($optionElement.parentElement.tagName == "SELECT" && $optionElement.closest($querySelector_filterContainer).querySelector($querySelector_transferValueToEl)) {
225                this.optionElement = $optionElement;
226                this.selectElement = this.optionElement.parentElement;
227                this.optionElementValueId = parseInt(this.optionElement.value);
228                this.transferValueToEl = this.selectElement.closest($querySelector_filterContainer).querySelector($querySelector_transferValueToEl);
229
230                if (this.#coordRegex.test(this.transferValueToEl.value)) {
231                    this.#transferValueToElHasValidCoordinates = true;
232                }
233
234            } else {
235                console.error("You passed an invalid Element-Structure or an wrong Selector");
236            }
237        } else {
238            console.error("You passed an invalid Argument!");
239        }
240    }
241
242    init() {
243        document.addEventListener("location-request", this.#boundHandleLocationRequest);
244        document.addEventListener("location-request-success", this.#boundHandleLocationRequestSuccess);
245        document.addEventListener("location-request-error", this.#boundHandleLocationRequestError);
246
247        //Has to be added outside promise bco eventlistener order
248        this.selectElement.addEventListener("change", this.#boundHandleLocationRequestInvoke);
249
250        this.#clientLocationInstance.permission.then((permissionState) => {
251            if (permissionState == "granted" && !this.#transferValueToElHasValidCoordinates) {
252                this.#removeInvokeListener();
253                this.#clientLocationInstance.requestLocation().catch((error) => { console.debug(error) });
254            } else if (permissionState == "denied") {
255                this.#destroy();
256            }
257
258            if (this.#transferValueToElHasValidCoordinates) {
259                this.#removeInvokeListener();
260                this.#removeLocationRequestListener();
261                this.#removeLocationRequestSuccessListener();
262                this.#removeLocationRequestErrorListener();
263            }
264        }).catch((error) => {
265            this.#destroy();
266
267            console.error("L3G0 Location: Error occoured while requesting permission for location.\n" + error.message);
268        });
269    }
270
271    //Method: Handles when user invoked manually
272    #handleLocationRequestInvoke(event) {
273        if (this.selectElement.value != this.optionElementValueId) {
274            return
275        }
276
277        event.stopImmediatePropagation();
278
279        this.#invokedOrderChange = true;
280        this.#removeInvokeListener();
281        this.#clientLocationInstance.requestLocation().catch((error) => { console.debug(error) });
282    }
283
284    //Method: Handles location request
285    #handleLocationRequest(event) {
286        this.#removeLocationRequestListener();
287    }
288
289    //Method: Handles successful location request. 
290    #handleLocationRequestSuccess(event) {
291        this.#removeInvokeListener();
292        this.#removeLocationRequestSuccessListener();
293        this.#removeLocationRequestErrorListener();
294
295        const clientLat = event.detail.coords.latitude;
296        const clientLon = event.detail.coords.longitude;
297
298        this.transferValueToEl.value = (clientLat + "," + clientLon);
299
300        if (this.#coordRegex.test(this.transferValueToEl.value)) {
301            this.#transferValueToElHasValidCoordinates = true;
302        }
303
304        if (this.instantSubmit && this.#invokedOrderChange && this.#invokedOrderChange) {
305            this.selectElement.closest("#aspnetForm").submit();
306        }
307    }
308
309    //Mehtod: Handles error while requesting location. 
310    #handleLocationRequestError(event) {
311        this.#destroy();
312
313        console.error("L3G0 Location: Error occoured while requesting location.\n" + event.detail.message);
314    }
315
316    //Method: Initializes ClientLocationData Instance
317    #getClientLocation(options) {
318        return new ClientLocationData(options);
319    }
320
321    //Method: Removes all Eventlisteners and removes dataContainer from DOM 
322    #destroy() {
323        this.#removeInvokeListener();
324        this.#removeLocationRequestListener();
325        this.#removeLocationRequestSuccessListener();
326        this.#removeLocationRequestErrorListener();
327        this.#removeEl();
328    }
329
330    //Method: Remove DataContainer from DOM
331    #removeEl() {
332        this.optionElement.remove();
333    }
334
335    //Method Group: Removing diverse eventListener
336    #removeInvokeListener() {
337        this.selectElement.removeEventListener("change", this.#boundHandleLocationRequestInvoke);
338    }
339
340    #removeLocationRequestListener() {
341        document.removeEventListener("location-request", this.#boundHandleLocationRequest);
342    }
343
344    #removeLocationRequestSuccessListener() {
345        document.removeEventListener("location-request-success", this.#boundHandleLocationRequestSuccess);
346    }
347
348    #removeLocationRequestErrorListener() {
349        document.removeEventListener("location-request-error", this.#boundHandleLocationRequestError);
350    }
351}
352
353class ClientLocationData {
354    #options;
355
356    constructor() {
357        if (navigator.geolocation) {
358            this.#options = arguments[0]
359        } else {
360            console.error("This Client does not support the Browser GeoLocation API");
361        }
362    }
363
364    get permission() {
365        return new Promise((resolve, reject) => {
366            navigator.permissions.query({ name: "geolocation" }).then((permission) => {
367                resolve(permission.state);
368            }).catch((error) => {
369                reject(error);
370            });
371        });
372    }
373
374    requestLocation() {
375        const eventLocation_Request = new Event("location-request");
376        document.dispatchEvent(eventLocation_Request);
377
378        return new Promise((resolve, reject) => {
379            this.#getLocPromise().then((GeolocationPositionObj) => {
380                const eventLocation_RequestSuccess = new CustomEvent("location-request-success", { detail: GeolocationPositionObj });
381                document.dispatchEvent(eventLocation_RequestSuccess);
382
383                resolve(GeolocationPositionObj);
384            }).catch((error) => {
385                const eventLocation_RequestError = new CustomEvent("location-request-error", { detail: error });
386                document.dispatchEvent(eventLocation_RequestError);
387
388                reject(error);
389            });
390        });
391    }
392
393    #getLocPromise() {
394        return new Promise((resolve, reject) => {
395            navigator.geolocation.getCurrentPosition(resolve, reject, this.#options);
396        });
397    }
398}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.