PageSourceSearch

https://scottishmedicines.org.uk/App_Plugins/Terratype.GoogleMapsV…atype.GoogleMapsV3.Renderer.js?cache=1.0.13

js scottishmedicines.org.uk collected 2026-10-02 03:44:36 UTC 21,453 bytes, 528 lines download raw bytes

1(function (root) {
2    var q = {
3        poll: 100,
4        jqueryLoadWait: 30,
5        markerClustererUrl: document.getElementsByClassName('Terratype.GoogleMapsV3')[0].getAttribute('data-markerclusterer-url'),
6        maps: [],
7        mapTypeIds: function (basic, satellite, terrain) {
8            var mapTypeIds = [];
9            if (basic) {
10                mapTypeIds.push('roadmap');
11            }
12            if (satellite) {
13                mapTypeIds.push('satellite');
14            }
15            if (terrain) {
16                mapTypeIds.push('terrain');
17            }
18
19            if (mapTypeIds.length == 0) {
20                mapTypeIds.push('roadmap');
21            }
22            return mapTypeIds;
23        },
24        init: function () {
25            q.load();
26            if (q.domDetectionType == 1) {
27                counter = 0;
28                var t = setInterval(function () {
29                    //  Is jquery loaded
30                    if (root.jQuery) {
31                        clearInterval(t);
32                        q.updateJquery();
33                    }
34                    if (++counter > q.jqueryLoadWait) {
35                        //  We have waited long enough for jQuery to load, and nothing, so default to javascript
36                        console.warn("Terratype was asked to use jQuery to monitor DOM changes, yet no jQuery library was detected. Terratype has defaulted to using javascript to detect DOM changes instead");
37                        clearInterval(t);
38                        q.domDetectionType = 0;
39                        q.updateJs();
40                    }
41                }, q.poll);
42            } else {
43                q.updateJs();
44            }
45        },
46        updateJs: function () {
47            //  Use standard JS to monitor page resizes, dom changes, scrolling
48            var counter = 0;
49            var mapsRunning = 0;
50            var timer = setInterval(function () {
51                if (counter == q.maps.length) {
52                    if (mapsRunning == 0) {
53                        //  There are no maps running
54                        clearInterval(timer);
55                    }
56                    counter = 0;
57                    mapsRunning = 0;
58                }
59                var m = q.maps[counter];
60                if (m.status != -1 && m.positions.length != 0) {
61                    mapsRunning++;
62                    if (m.status == 0) {
63                        q.render(m);
64                    } else {
65                        if (m.domDetectionType == 2) {
66                            m.status = -1;
67                        } else if (m.domDetectionType == 1 && root.jQuery) {
68                            q.idleJquery(m);
69                        } else {
70                            q.idleJs(m);
71                        }
72                    }
73                }
74                counter++;
75            }, q.poll);
76        },
77        updateJquery: function () {
78            //  Can only be used, if all DOM updates happen via jQuery.
79            var counter = 0;
80            var timer = setInterval(function () {
81                if (counter == q.maps.length) {
82                    clearInterval(timer);
83                    if (q.domDetectionType != 2) {
84                        jQuery(window).on('DOMContentLoaded load resize scroll touchend', function () {
85                            counter = 0;
86                            var timer2 = setInterval(function () {
87                                if (counter == q.maps.length) {
88                                    clearInterval(timer2);
89                                } else {
90                                    var m = q.maps[counter];
91                                    if (m.status > 0 && m.positions.length != 0) {
92                                        if (m.domDetectionType == 1) {
93                                            q.idleJquery(m);
94                                        } else {
95                                            q.idleJs(m);
96                                        }
97                                    }
98                                    counter++;
99                                }
100                            }, q.poll);
101                        });
102                    }
103                } else {
104                    var m = q.maps[counter];
105                    if (m.status == 0 && m.positions.length != 0) {
106                        q.render(m);
107                    }
108                    counter++;
109                }
110            }, q.poll);
111        },
112        getMap: function (mapId) {
113            for (var i = 0; i != q.maps.length; i++) {
114                if (q.maps[i].id == mapId) {
115                    return q.maps[i];
116                }
117            }
118            return null;
119        },
120        defaultProvider: {
121            predefineStyling: 'retro',
122            showRoads: true,
123            showLandmarks: true,
124            showLabels: true,
125            variety: {
126                basic: true,
127                satellite: false,
128                terrain: false,
129                selector: {
130                    type: 1,     // Horizontal Bar
131                    position: 0  // Default
132                }
133            },
134            streetView: {
135                enable: false,
136                position: 0
137            },
138            fullscreen: {
139                enable: false,
140                position: 0
141            },
142            scale: {
143                enable: false,
144                position: 0
145            },
146            zoomControl: {
147                enable: true,
148                position: 0,
149            },
150            panControl: {
151                enable: false
152            },
153            draggable: true
154        },
155        mergeJson: function (aa, bb) {        //  Does not merge arrays
156            var mi = function (c) {
157                var t = {};
158                for (var k in c) {
159                    if (typeof c[k] === 'object' && c[k].constructor.name !== 'Array') {
160                        t[k] = mi(c[k]);
161                    } else {
162                        t[k] = c[k];
163                    }
164                }
165                return t;
166            }
167            var mo = function (a, b) {
168                var r = (a) ? mi(a) : {};
169                if (b) {
170                    for (var k in b) {
171                        if (r[k] && typeof r[k] === 'object' && r[k].constructor.name !== 'Array') {
172                            r[k] = mo(r[k], b[k]);
173                        } else {
174                            r[k] = b[k];
175                        }
176                    }
177                }
178                return r;
179            }
180            return mo(aa, bb);
181        },
182        domDetectionType: 99,
183        load: function () {
184            var matches = document.getElementsByClassName('Terratype.GoogleMapsV3');
185            for (var i = 0; i != matches.length; i++) {
186                mapId = matches[i].getAttribute('data-map-id');
187                id = matches[i].getAttribute('data-id');
188                var domDetectionType = parseInt(matches[i].getAttribute('data-dom-detection-type'));
189                if (q.domDetectionType > domDetectionType) {
190                    q.domDetectionType = domDetectionType;
191                }
192                var model = JSON.parse(unescape(matches[i].getAttribute('data-googlemapsv3')));
193                var datum = q.parse(model.position.datum);
194                var latlng = new root.google.maps.LatLng(datum.latitude, datum.longitude);
195                var m = q.getMap(mapId);
196                if (m == null) {
197                    m = {
198                        id: mapId,
199                        div: id,
200                        zoom: model.zoom,
201                        provider: q.mergeJson(q.defaultProvider, model.provider),
202                        positions: [],
203                        center: latlng,
204                        divoldsize: 0,
205                        status: 0,
206                        visible: false,
207                        domDetectionType: domDetectionType
208                    };
209                    matches[i].style.display = 'block';
210                    q.maps.push(m);
211                }
212                if (model.icon && model.icon.url) {
213                    m.positions.push({
214                        id: id,
215                        label: matches[i].getAttribute('data-label-id'),
216                        latlng: latlng,
217                        icon: {
218                            url: q.configIconUrl(model.icon.url),
219                            scaledSize: new root.google.maps.Size(model.icon.size.width, model.icon.size.height),
220                            anchor: new root.google.maps.Point(
221                                q.getAnchorHorizontal(model.icon.anchor.horizontal, model.icon.size.width),
222                                q.getAnchorVertical(model.icon.anchor.vertical, model.icon.size.height))
223                        }
224                    });
225                }
226            }
227        },
228        render: function (m) {
229            m.ignoreEvents = 0;
230            var mapTypeIds = q.mapTypeIds(m.provider.variety.basic, m.provider.variety.satellite, m.provider.variety.terrain);
231            m.gmap = new root.google.maps.Map(document.getElementById(m.div), {
232                disableDefaultUI: false,
233                scrollwheel: false,
234                panControl: false,      //   Has been depricated
235                center: m.center,
236                zoom: m.zoom,
237                draggable: true,
238                fullScreenControl: m.provider.fullscreen.enable,
239                fullscreenControlOptions: m.provider.fullscreen.position,
240                styles: m.provider.styles,
241                mapTypeId: mapTypeIds[0],
242                mapTypeControl: (mapTypeIds.length > 1),
243                mapTypeControlOptions: {
244                    style: m.provider.variety.selector.type,
245                    mapTypeIds: mapTypeIds,
246                    position: m.provider.variety.selector.position
247                },
248                scaleControl: m.provider.scale.enable,
249                scaleControlOptions: {
250                    position: m.provider.scale.position
251                },
252                streetViewControl: m.provider.streetView.enable,
253                streetViewControlOptions: {
254                    position: m.provider.streetView.position
255                },
256                zoomControl: m.provider.zoomControl.enable,
257                zoomControlOptions: {
258                    position: m.provider.zoomControl.position
259                }
260            });
261            with ({
262                mm: m
263            }) {
264                root.google.maps.event.addListener(mm.gmap, 'zoom_changed', function () {
265                    if (mm.ignoreEvents > 0) {
266                        return;
267                    }
268                    q.closeInfoWindows(mm);
269                    mm.zoom = mm.gmap.getZoom();
270                });
271                root.google.maps.event.addListenerOnce(mm.gmap, 'tilesloaded', function () {
272                    if (mm.ignoreEvents > 0) {
273                        return;
274                    }
275                    q.refresh(mm);
276                    mm.status = 2;
277                });
278                root.google.maps.event.addListener(mm.gmap, 'resize', function () {
279                    if (mm.ignoreEvents > 0) {
280                        return;
281                    }
282                    q.checkResize(mm);
283                });
284                root.google.maps.event.addListener(mm.gmap, 'click', function () {
285                    if (mm.ignoreEvents > 0) {
286                        return;
287                    }
288                    q.closeInfoWindows(mm);
289                });
290            }
291            m.ginfos = [];
292            m.gmarkers = [];
293
294            for (var p = 0; p != m.positions.length; p++) {
295                var item = m.positions[p];
296                m.gmarkers[p] = new root.google.maps.Marker({
297                    map: m.gmap,
298                    position: item.latlng,
299                    id: item.id,
300                    draggable: false,
301                    icon: item.icon
302                });
303
304                m.ginfos[p] = null;
305                var l = (item.label) ? document.getElementById(item.label) : null;
306                if (l) {
307
308                    m.ginfos[p] = new root.google.maps.InfoWindow({
309                        content: l
310                    });
311                    with ({
312                        mm: m,
313                        pp: p
314                    }) {
315                        mm.gmarkers[p].addListener('click', function () {
316                            //console.warn(mm.id + ': iconClick(): ignoreEvents = ' + mm.ignoreEvents);
317                            if (mm.ignoreEvents > 0) {
318                                return;
319                            }
320                            q.closeInfoWindows(mm);
321                            if (mm.ginfos[pp] != null) {
322                                mm.ginfos[pp].open(mm.gmap, mm.gmarkers[pp]);
323                            }
324                        });
325                    }
326                }
327            }
328
329            if (m.positions.length > 1) {
330                m.markerclusterer = new MarkerClusterer(m.gmap, m.gmarkers, { imagePath: q.markerClustererUrl });
331            }
332            m.status = 1;
333        },
334        closeInfoWindows: function (m) {
335            for (var p = 0; p != m.positions.length; p++) {
336                if (m.ginfos[p] != null) {
337                    m.ginfos[p].close();
338                }
339            }
340        },
341        checkResize: function (m) {
342            if (!m.gmap.getBounds().contains(m.center)) {
343                q.refresh(m);
344            }
345        },
346        refresh: function (m) {
347            m.ignoreEvents++;
348            m.gmap.setZoom(m.zoom);
349            q.closeInfoWindows(m);
350            m.gmap.setCenter(m.center);
351            with ({
352                mm: m
353            }) {
354                root.google.maps.event.addListenerOnce(mm.gmap, 'idle', function () {
355                    if (mm.idle == null) {
356                        //console.warn(mm.id + ': refresh() end: already ran backup timer');
357                        return;
358                    }
359                    mm.ignoreEvents--;
360                    if (mm.ignoreEvents == 0) {
361                        mm.gmap.setCenter(mm.center);
362                        clearTimeout(mm.idle);
363                        mm.idle = null;
364                    }
365                    //console.warn(mm.id + ': refresh() end: ignoreEvents = ' + mm.ignoreEvents);
366                });
367                if (mm.idle) {
368                    clearTimeout(mm.idle);
369                }
370                mm.idle = setTimeout(function () {
371                    if (mm.ignoreEvents != 0) {
372                        //console.warn(mm.id + ': refresh() end: running backup timer');
373                        mm.gmap.setCenter(mm.center);
374                        mm.ignoreEvents = 0
375                    }
376                    clearTimeout(mm.idle);
377                    mm.idle = null;
378                }, 5000);
379            }
380            root.google.maps.event.trigger(m.gmap, 'resize');
381            //console.warn(m.id + ' refresh(): ignoreEvents = ' + m.ignoreEvents);
382        },
383        configIconUrl: function (url) {
384            if (typeof (url) === 'undefined' || url == null) {
385                return '';
386            }
387            if (url.indexOf('//') != -1) {
388                //  Is an absolute address
389                return url;
390            }
391            //  Must be a relative address
392            if (url.substring(0, 1) != '/') {
393                url = '/' + url;
394            }
395
396            return root.location.protocol + '//' + root.location.hostname + (root.location.port ? ':' + root.location.port : '') + url;
397        },
398        getAnchorHorizontal: function (text, width) {
399            if (typeof text == 'string') {
400                switch (text.charAt(0)) {
401                    case 'l':
402                    case 'L':
403                        return 0;
404
405                    case 'c':
406                    case 'C':
407                    case 'm':
408                    case 'M':
409                        return width / 2;
410
411                    case 'r':
412                    case 'R':
413                        return width - 1;
414                }
415            }
416            return Number(text);
417        },
418        getAnchorVertical: function (text, height) {
419            if (typeof text == 'string') {
420                switch (text.charAt(0)) {
421                    case 't':
422                    case 'T':
423                        return 0;
424
425                    case 'c':
426                    case 'C':
427                    case 'm':
428                    case 'M':
429                        return height / 2;
430
431                    case 'b':
432                    case 'B':
433                        return height - 1;
434                }
435            }
436            return Number(text);
437        },
438        parse: function (text) {
439            var args = text.trim().split(',');
440            if (args.length < 2) {
441                return false;
442            }
443            var lat = parseFloat(args[0].substring(0, 10));
444            if (isNaN(lat) || lat > 90 || lat < -90) {
445                return false;
446            }
447            var lng = parseFloat(args[1].substring(0, 10));
448            if (isNaN(lng) || lng > 180 || lng < -180) {
449                return false;
450            }
451            return {
452                latitude: lat,
453                longitude: lng
454            };
455        },
456        isElementInViewport: function (el) {
457            var rect = el.getBoundingClientRect();
458            return (
459                (rect.top <= (window.innerHeight || document.documentElement.clientHeight)) && ((rect.top + rect.height) >= 0) &&
460                (rect.left <= (window.innerWidth || document.documentElement.clientWidth)) && ((rect.left + rect.width) >= 0)
461            );
462        },
463        idleJs: function (m) {
464            //  Monitor dom changes via Javascript
465            var element = document.getElementById(m.div);
466            var newValue = element.parentElement.offsetTop + element.parentElement.offsetWidth;
467            var newSize = element.clientHeight * element.clientWidth;
468            var show = !(element.style.display && typeof element.style.display == 'string' && element.style.display.toLowerCase() == 'none');
469            var visible = show && q.isElementInViewport(element);
470            if (newValue != 0 && show == false) {
471                //console.log('A ' + m.id + ': in viewport = ' + visible + ', showing = ' + show);
472                //  Was hidden, now being shown
473                document.getElementById(m.div).style.display = 'block';
474            } else if (newValue == 0 && show == true) {
475                //console.log('B ' + m.id + ': in viewport = ' + visible + ', showing = ' + show);
476                //  Was shown, now being hidden
477                document.getElementById(m.div).style.display = 'none';
478                m.visible = false;
479            }
480            else if (visible == true && m.divoldsize != 0 && newSize != 0 && m.divoldsize != newSize) {
481                //console.log('C ' + m.id + ': in viewport = ' + visible + ', showing = ' + show);
482                //  showing, just been resized and map is visible
483                q.refresh(m);
484                m.visible = true;
485            } else if (visible == true && m.visible == false) {
486                //console.log('D ' + m.id + ': in viewport = ' + visible + ', showing = ' + show);
487                //  showing and map just turned visible
488                q.refresh(m);
489                m.visible = true;
490            } else if (visible == false && m.visible == true) {
491                //console.log('E ' + m.id + ': in viewport = ' + visible + ', showing = ' + show);
492                //  was visible, but now hiding
493                m.visible = false;
494            }
495            m.divoldsize = newSize;
496        },
497        idleJquery: function (m) {
498            //  Monitor dom changes via jQuery
499            var element = jQuery(document.getElementById(m.div));
500            var show = !(element.is(':hidden'));
501            var visible = element.is(':visible');
502            if (show == visible) {
503                if (show) {
504                    var newSize = element.height() * element.width();
505                    if (newSize != m.divoldsize) {
506                        q.refresh(m);
507                    }
508                    m.divoldsize = newSize;
509                }
510                return;
511            }
512            if (show) {
513                element.hide();
514                m.divoldsize = 0;
515                return;
516            }
517            element.show();
518            q.refresh(m);
519            m.divoldsize = element.height() * element.width();
520        }
521    }
522
523    root.TerratypeGoogleMapsV3CallbackRender = function () {
524        q.init();
525    }
526}(window));
527
528

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.