PageSourceSearch

https://www.harrywinston.com/-/media/base-themes/maps/scripts/comp…=-1&hash=C5A27AF2C33B3070D0DFAA954F1D2836

js harrywinston.com collected 2026-10-02 06:21:42 UTC 20,246 bytes, 487 lines download raw bytes

1XA.component.map = (function ($, document) {
2
3    "use strict";
4
5    var api = {},
6        maps = [],
7        searchEndpoint,
8        searchResultsSignatures = [],
9        key,
10        urlHelperModel,
11        apiModel,
12        queryModel,
13        mapsConnector,
14        scriptsLoaded = false,
15        initialize,
16        searchResults,
17        pushMapData,
18        resultsLoaded,
19        myLocationChanged,
20        myLocationData,
21        mapViews = [],
22        MapModel,
23        MapView;
24
25    resultsLoaded = function (data) {
26        searchResults = data;
27    };
28
29    myLocationChanged = function (data) {
30        myLocationData = data;
31    };
32
33    initialize = function () {
34        var i, mapsCount = maps.length;
35        for (i = 0; i < mapsCount; i++) {
36            //crate Backbone.js views - one view per component on the page
37            mapViews.push(new MapView({el: maps[i], model: new MapModel()}));
38        }
39        if (typeof (XA.component.search) !== "undefined") {
40            pushMapData();
41        }
42    };
43
44    pushMapData = function() {
45        var notInitializedMaps,
46            resultsExists = typeof searchResults !== "undefined",
47            myLocationExists = typeof myLocationData !== "undefined";
48
49        if (resultsExists || myLocationExists) {
50            //in case that results were loaded before initialization of view and model, trigger another event with
51            //previously loaded results
52            //this will happen just once - while initialization
53            //remember about checking if all maps are already rendered
54            notInitializedMaps = mapViews.filter(function (view) {
55                if (view.model.get("showed") === false) {
56                    return true;
57                }
58                return false;
59            });
60
61            if (notInitializedMaps.length > 0) {
62                setTimeout(pushMapData, 1000);
63            } else {
64                if (resultsExists) {
65                    XA.component.search.vent.trigger("internal-results-loaded", searchResults);
66                }
67                if (myLocationExists) {
68                    XA.component.search.vent.trigger("internal-my-location-coordinates-changed", myLocationData);
69                }
70            }
71        }
72    };
73
74    MapModel = Backbone.Model.extend({
75        defaults: {
76            dataProperties: {},
77            dynamicPoiList: [],
78            showed: false,
79            myLocation: ["", ""],
80            id: null,
81            loadMore: false
82        },
83        initialize: function() {
84            var sig = this.get("dataProperties").searchResultsSignature,
85                hash = queryModel.parseHashParameters(window.location.hash),
86                param = typeof (sig) !== "undefined" && sig !== "" ? sig + "_g" : "g";
87
88            if (typeof (XA.component.search) !== "undefined") {
89                XA.component.search.vent.on("results-loaded", this.updateDynamicPoiList.bind(this));
90                XA.component.search.vent.on("internal-results-loaded", this.updateDynamicPoiList.bind(this));
91                XA.component.search.vent.on("my-location-coordinates-changed", this.changeMyLocation.bind(this));
92                XA.component.search.vent.on("internal-my-location-coordinates-changed", this.changeMyLocation.bind(this));
93                XA.component.search.vent.on("hashChanged", this.hashChanged.bind(this));
94            }
95
96            if (hash.hasOwnProperty(param) && hash[param] !== "") {
97                //if Location Filter component is on the page it could already fill "g" hash parameter
98                this.set("myLocation", hash[param].split("|"));
99            }
100        },
101        getPoiVariant: function (poiTypeId, poiVariantId) {
102            var mapping = this.get("dataProperties").typeToVariantMapping,
103                typeId;
104
105            if (typeof poiTypeId !== "undefined" && poiTypeId != null) {
106                typeId = "{" + poiTypeId.toUpperCase() + "}";
107                if (mapping.hasOwnProperty(typeId)) {
108                    return mapping[typeId];
109                } else {
110                    return poiVariantId;
111                }
112            }
113            return poiVariantId;
114        },
115        updateDynamicPoiList: function(searchResults) {
116            var dynamicPoiList = [],
117                signature = this.get("dataProperties").searchResultsSignature,
118                geolocationData = searchResults.data.filter(function (result) {
119                    if (result.hasOwnProperty("Geospatial")) {
120                        return true;
121                    } else {
122                        return false;
123                    }
124                }),
125                i,
126                poi;
127
128            if (signature !== searchResults.searchResultsSignature) {
129                return;
130            }
131
132            //save information that those POIs comes from load more action
133            this.set("loadMore", searchResults.loadMore);
134
135            for (i = 0; i < geolocationData.length; i++) {
136                poi = geolocationData[i];
137
138                //don't show POIs which doesn't have Latitude and Longitude
139                if (poi.Geospatial.Latitude === 0 || poi.Geospatial.Longitude === 0) {
140                    continue;
141                }
142
143                dynamicPoiList.push({
144                    id: poi.Id,
145                    type: "Dynamic",
146                    title: poi.Name,
147                    latitude: poi.Geospatial.Latitude,
148                    longitude: poi.Geospatial.Longitude,
149                    icon: poi.Geospatial.PoiIcon,
150                    poiTypeId: poi.Geospatial.PoiTypeId,
151                    poiVariantId: this.getPoiVariant(poi.Geospatial.PoiTypeId, poi.Geospatial.PoiVariantId),
152                    html: poi.Html
153                });
154            }
155
156            this.set("dynamicPoiList", dynamicPoiList);
157        },
158        changeMyLocation: function (myLocationData) {
159            var sig = this.get("dataProperties").searchResultsSignature;
160            if (sig === myLocationData.sig) {
161                this.set("myLocation", myLocationData.coordinates);
162            }
163        },
164        hashChanged: function (hash) {
165            var sig = this.get("dataProperties").searchResultsSignature,
166                location = hash[sig !== "" ? sig + "_g" : "g"],
167                myLocationDataSignature = typeof myLocationData !== "undefined" ? myLocationData.sig : "",
168                parts;
169
170            if (sig === myLocationDataSignature && typeof location !== "undefined" && location !== null && location !== "") {
171                parts = location.split("|");
172                if (parts.length > 1) {
173                    this.set("myLocation", [parts[0], parts[1]]);
174                }
175            }
176        }
177    });
178
179    MapView = Backbone.View.extend({
180        initialize : function () {
181            var dataProperties = this.$el.data(),
182                properties = dataProperties.properties;
183
184            if (this.model) {
185                this.model.set({dataProperties: properties});
186                this.model.set({id: this.$el.find(".map-canvas").prop("id")});
187            }
188
189            this.render();
190            this.model.on("change:dynamicPoiList", this.renderDynamicPois, this);
191            this.model.on("change:myLocation", this.updateMyLocationPoi, this);
192            if (typeof (XA.component.search) !== "undefined") {
193                XA.component.search.vent.on("center-map", this.handleCenterMap.bind(this));
194            }
195            this.updateMyLocationPoi();
196
197        },
198        render : function () {
199            var that = this,
200                showed = this.model.get("showed"),
201                canvas = document.getElementById(this.model.get("id"));
202
203            if (!showed && canvas !== null) {
204                this.getCentralPoint(function (viewBounds, ctx) {
205                    if (typeof viewBounds !== "undefined") {
206                        var context = typeof ctx !== "undefined" ? ctx : this,
207                            id = context.model.get("id"),
208                            properties = context.model.get("dataProperties"),
209                            mapOptions = {
210                                canvasId: id,
211                                zoom: typeof(properties.zoom) === "number" ? properties.zoom : context.parseZoom(properties.zoom, 15),
212                                mode: properties.mode,
213                                poiCount: properties.pois.length,
214                                key: properties.key,
215                                disableMapScrolling: properties.disableMapScrolling,
216                                disableMapZoomOnScroll: properties.disableMapZoomOnScroll
217                            };
218
219                        mapsConnector.showMap(id, mapOptions, viewBounds);
220                        context.renderPoiList(id, properties.pois);
221
222                        context.model.set("showed", true);
223                    }
224                });
225            }
226        },
227        renderDynamicPois: function() {
228            var dataProperties = this.model.get("dataProperties"),
229                dynamicPoiList = this.model.get("dynamicPoiList"),
230                properties = this.model.get("dataProperties"),
231                id = this.model.get("id"),
232                i;
233
234            if (!this.model.get("loadMore")) {
235                mapsConnector.clearMarkers(id);
236            }
237
238            for (i = 0; i < dynamicPoiList.length; i++) {
239                mapsConnector.renderDynamicPoi(id, dynamicPoiList[i], this.getGeoPoiContent.bind(this));
240            }
241
242            //if user want to see all POIs then after adding dynamic POIs we have to recalculate map center point
243            if (dataProperties.centralPointMode === "MidOfPoi") {
244                mapsConnector.updateMapPosition(this.model.get("id"), this.parseZoom(properties.zoom, 15));
245            }
246
247            if (mapsConnector.createClusters) {
248                mapsConnector.createClusters(id);
249            }
250        },
251        renderPoiList: function(mapId, poiList) {
252            var i,
253                poi,
254                myLocation,
255                poiCount = poiList.length,
256                properties = this.model.get("dataProperties"),
257                sig = properties.searchResultsSignature,
258                hash = queryModel.parseHashParameters(window.location.hash),
259                param = sig !== "" ? sig + "_g" : "g";
260
261            for (i = 0; i < poiCount; i++) {
262                poi = poiList[i];
263                var zIndex = '';
264                var poiIcon = poi.PoiIcon;
265
266                if (poi.Type === "MyLocation") {
267                    myLocation = this.model.get("myLocation");
268                    poi.Latitude = myLocation[0];
269                    poi.Longitude = myLocation[1];
270
271                    if (!hash.hasOwnProperty(param) || (hash.hasOwnProperty(param) && hash[param] === "")) {
272                        //if there is no "g" param then it's mean that there is no Location Filter on the map
273                        //in this case we have take coordinated from the browser to display My Location POI
274                        this.getCurrentPosition(function (coordinates) {
275                            this.model.set("myLocation", coordinates);
276                        });
277                    } else if (hash.hasOwnProperty(param)) {
278                        this.model.set("myLocation", hash[param].split("|"));
279                    }
280                } else if (poi.Latitude === "" || poi.Longitude === "") {
281                    continue;
282                }
283
284                if (poiIcon !== null && poiIcon !== '') {
285                    if (poiIcon.indexOf('Salon') !== -1) {
286                        zIndex = 150;
287                    } else {
288                        zIndex = 100;
289                    }
290                }
291
292                mapsConnector.renderPoi(mapId, {
293                    id: poi.Id.Guid,
294                    title: poi.Title,
295                    description: poi.Description,
296                    latitude: poi.Latitude,
297                    longitude: poi.Longitude,
298                    icon: poi.PoiIcon,
299                    html: poi.Html,
300                    type: poi.Type,
301                    zIndex: zIndex
302                });
303            }
304        },
305        getPoiContent: function(poiId, poiTypeId, poiVariantId, renderPoiContentCallback) {
306            var properties = this.model.get("dataProperties"),
307                url = urlHelperModel.createGetPoiContentUrl({endpoint: properties.variantsEndpoint}, poiId, poiVariantId);
308
309            apiModel.getData({
310                callback: renderPoiContentCallback,
311                url: url,
312                excludeSiteName: true
313            });
314        },
315        getGeoPoiContent: function (poiId, poiTypeId, poiVariantId, renderPoiContentCallback) {
316            console.log(this.model);
317            var myLocation = this.model.get("myLocation"),
318                latitude = myLocation[0],
319                longitude = myLocation[1],
320                properties = this.model.get("dataProperties"),
321                hash = queryModel.parseHashParameters(window.location.hash),
322                units = hash.o,
323                url = urlHelperModel.createGetGeoPoiContentUrl({ endpoint: properties.variantsEndpoint }, poiId, poiVariantId, latitude + "," + longitude, units, properties.itemId);
324
325            apiModel.getData({
326                callback: renderPoiContentCallback,
327                url: url,
328                excludeSiteName: true
329            });
330
331        },
332        getCentralPoint: function (callback) {
333            var properties = this.model.get("dataProperties"),
334                that = this;
335
336            switch (properties.centralPointMode) {
337                case "Auto": {
338                    if (properties.centralPoint !== "") {
339                        callback.call(that, [properties.latitude, properties.longitude]);
340                    } else if (properties.pois.length > 0) {
341                        callback.call(that, [properties.pois[0].Latitude, properties.pois[0].Longitude]);
342                    } else {
343                        this.getCurrentPosition(callback);
344                    }
345                    break;
346                }
347                case "MidOfPoi": {
348                    callback.call(that, this.getPoisCentralPoint());
349                    break;
350                }
351                case "Location":{
352                    this.getCurrentPosition(callback);
353                    break;
354                }
355            }
356        },
357        getCurrentPosition: function (callback) {
358          var that = this;
359          XA.component.locationService.detectLocation(
360              function (location) {
361                  callback.call(that, location, that);
362              },
363              function (errorMessage) {
364                  callback.call(that, [0, 0], that);
365                  console.log(errorMessage);
366              }
367          );
368        },
369        getPoisCentralPoint: function () {
370            var i,
371                poi,
372                poisCoords = [],
373                myLocation = this.model.get("myLocation"),
374                properties = this.model.get("dataProperties"),
375                count = properties.pois.length;
376
377            for (i = 0; i < count; i++) {
378                poi = properties.pois[i];
379                if (poi.TemplateId.Guid === "7dd9ece5-9461-498d-8721-7cbea8111b5e") {
380                    if (myLocation[0] !== "" && myLocation[1] !== "") {
381                        poi.Latitude = myLocation[0];
382                        poi.Longitude = myLocation[1];
383                        this.model.set("dataProperties", properties);
384                        poisCoords.push({latitude: poi.Latitude, longitude: poi.Longitude});
385                    }
386                } else {
387                    poisCoords.push({latitude: poi.Latitude, longitude: poi.Longitude});
388                }
389            }
390
391            return mapsConnector.getCentralPoint(poisCoords);
392        },
393        handleCenterMap: function (data) {
394            var centerMap = this.model.get("dataProperties").centerOnFoundPoi === "1",
395                animate = this.model.get("dataProperties").animateFoundPoi === "1";
396            this.centerOnMap(data, centerMap, animate);
397        },
398        centerOnMap: function (data, centerMap, animate) {
399            if (data.sig === this.model.get("dataProperties").searchResultsSignature) {
400                mapsConnector.centerMap(this.model.get("id"), data, centerMap, animate);
401            }
402        },
403        updateMyLocationPoi: function () {
404            var properties = this.model.get("dataProperties"),
405                myLocation = this.model.get("myLocation");
406
407            //check if there is something in my location
408            if (myLocation[0] !== "" && myLocation[1] !== 0) {
409                //my location was changed so update position of My Location marker
410                mapsConnector.updateMyPoiLocation(this.model.get("id"), myLocation, this.parseZoom(properties.zoom, 15));
411            } else if (properties.latitude !== "" && properties.longitude !== "") {
412                var data = {};
413                data.sig = properties.searchResultsSignature;
414                data.coordinates = [properties.latitude, properties.longitude];
415                this.centerOnMap(data, true, false);
416            }
417        },
418        parseZoom: function (str, defaultValue) {
419            var retValue = defaultValue;
420            if(str !== null) {
421                if(str.length > 0) {
422                    if (!isNaN(str)) {
423                        retValue = parseInt(str);
424                    }
425                }
426            }
427            return retValue;
428        }
429    });
430
431    api.init = function() {
432        var i,
433            mapElements = $(".map.component:not(.initialized)"),
434            count = mapElements.length;
435
436        if (typeof (XA.component.search) !== "undefined") {
437            queryModel = XA.component.search.query;
438            urlHelperModel = XA.component.search.url;
439            apiModel = XA.component.search.ajax;
440
441            //if the page was reloaded there could be situation that search results will load results faster then map initialization
442            //so that we have to save them and pass to the models when they will be created
443            XA.component.search.vent.on("results-loaded", resultsLoaded);
444            //the same with "my location", sometimes Location Filter component can change location before map was initialized
445            XA.component.search.vent.on("my-location-coordinates-changed", myLocationChanged);
446        }
447        mapsConnector = XA.connector.mapsConnector;
448
449        if (count > 0) {
450            for (i = 0; i < count; i++) {
451                var $map = $(mapElements[i]);
452                var properties = $map.data("properties");
453                key = properties.key;
454                searchEndpoint = properties.endpoint;
455                if (properties.pois.length > 0 && properties.searchResultsSignature !== "") {
456                    searchResultsSignatures.push(properties.searchResultsSignature);
457                }
458                $map.addClass("initialized");
459                maps.push($map);
460            }
461
462            if (!scriptsLoaded) {
463                mapsConnector.loadScript(key, XA.component.map.scriptsLoaded);
464            } else {
465                initialize();
466            }
467        }
468    };
469
470    api.scriptsLoaded = function() {
471        scriptsLoaded = true;
472        initialize();
473    };
474
475    api.getSearchEndpoint = function() {
476        return searchEndpoint;
477    };
478
479    api.getSignatures = function() {
480        return searchResultsSignatures;
481    }
482
483    return api;
484
485}(jQuery, document));
486
487XA.register("map", XA.component.map);

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.