1/** 2 * @namespace WPGMZA 3 * @module InfoWindow 4 * @requires WPGMZA.EventDispatcher 5 */ 6jQuery(function($) { 7 8 /** 9 * Base class for infoWindows. This acts as an abstract class so that infoWindows for both Google and OpenLayers can be interacted with seamlessly by the overlying logic. <strong>Please <em>do not</em> call this constructor directly. Always use createInstance rather than instantiating this class directly.</strong> Using createInstance allows this class to be externally extensible. 10 * @class WPGMZA.InfoWindow 11 * @constructor WPGMZA.InfoWindow 12 * @memberof WPGMZA 13 * @see WPGMZA.InfoWindow.createInstance 14 */ 15 WPGMZA.InfoWindow = function(feature) { 16 var self = this; 17 18 19 20 WPGMZA.EventDispatcher.call(this); 21 22 WPGMZA.assertInstanceOf(this, "InfoWindow"); 23 24 this.on("infowindowopen", function(event) { 25 self.onOpen(event); 26 }); 27 28 if(!feature) 29 return; 30 31 this.feature = feature; 32 this.state = WPGMZA.InfoWindow.STATE_CLOSED; 33 34 if(feature.map) 35 { 36 // This has to be slightly delayed so the map initialization won't overwrite the infowindow element 37 setTimeout(function() { 38 self.onFeatureAdded(event); 39 }, 100); 40 } 41 else 42 feature.addEventListener("added", function(event) { 43 self.onFeatureAdded(event); 44 }); 45 } 46 47
48 49 WPGMZA.InfoWindow.prototype = Object.create(WPGMZA.EventDispatcher.prototype); 50 WPGMZA.InfoWindow.prototype.constructor = WPGMZA.InfoWindow; 51 52 WPGMZA.InfoWindow.OPEN_BY_CLICK = 1; 53 WPGMZA.InfoWindow.OPEN_BY_HOVER = 2; 54 55 WPGMZA.InfoWindow.STATE_OPEN = "open"; 56 WPGMZA.InfoWindow.STATE_CLOSED = "closed"; 57 58 /** 59 * Fetches the constructor to be used by createInstance, based on the selected maps engine 60 * @method 61 * @memberof WPGMZA.InfoWindow 62 * @return {function} The appropriate constructor 63 */ 64 WPGMZA.InfoWindow.getConstructor = function() 65 { 66 switch(WPGMZA.settings.engine) 67 { 68 case "open-layers": 69 case "open-layers-latest": 70 if(WPGMZA.isProVersion()) 71 return WPGMZA.OLProInfoWindow; 72 return WPGMZA.OLInfoWindow; 73 break; 74 case "leaflet": 75 case "leaflet-azure": 76 case "leaflet-stadia": 77 case "leaflet-maptiler": 78 case "leaflet-locationiq": 79 case "leaflet-zerocost": 80 if(WPGMZA.isProVersion()) 81 return WPGMZA.LeafletProInfoWindow; 82 return WPGMZA.LeafletInfoWindow; 83 break; 84 default: 85 if(WPGMZA.isProVersion()) 86 return WPGMZA.GoogleProInfoWindow; 87 return WPGMZA.GoogleInfoWindow; 88 break; 89 } 90 } 91 92 /** 93 * Creates an instance of an InfoWindow, <strong>please <em>always</em> use this function rather than calling the constructor directly</strong> 94 * @method 95 * @memberof WPGMZA.InfoWindow 96 * @param {object} options Options for the object (optional) 97 */ 98 WPGMZA.InfoWindow.createInstance = function(feature) 99 { 100 var constructor = this.getConstructor(); 101 return new constructor(feature); 102 } 103 104 Object.defineProperty(WPGMZA.InfoWindow.prototype, "content", { 105 106 "get": function() 107 { 108 return this.getContent(); 109 }, 110 111 "set": function(value) 112 { 113 this.contentHtml = value; 114 } 115 }); 116 117 118 WPGMZA.InfoWindow.prototype.addEditButton = function() { 119 if (WPGMZA.currentPage == "map-edit") { 120 if(this.feature instanceof WPGMZA.Marker){ 121 let buttons = '<a title="Edit this marker" style="width:15px;" class="wpgmza_edit_btn" data-edit-marker-id="'+this.feature.id+'"><i class="fa fa-edit"></i></a>'; 122 buttons += this.addDeleteButton(); 123 return ' ' + buttons; 124 } 125 } 126 return ''; 127 } 128 129 WPGMZA.InfoWindow.prototype.addDeleteButton = function(){ 130 if (WPGMZA.currentPage == "map-edit") { 131 if(this.feature instanceof WPGMZA.Marker){ 132 return' <a title="Delete this marker" style="width:15px;" class="wpgmza_del_btn" data-delete-marker-id="'+this.feature.id+'"><i class="fa fa-trash"></i></a>'; 133 } 134 } 135 return ''; 136 } 137 138 WPGMZA.InfoWindow.prototype.workOutDistanceBetweenTwoMarkers = function(location1, location2) { 139 if(!location1 || !location2) 140 return; // No location (no search performed, user location unavailable) 141 142 var distanceInKM = WPGMZA.Distance.between(location1, location2); 143 var distanceToDisplay = distanceInKM; 144 145 if(this.distanceUnits == WPGMZA.Distance.MILES) 146 distanceToDisplay /= WPGMZA.Distance.KILOMETERS_PER_MILE; 147 148 var text = Math.round(distanceToDisplay, 2); 149 150 return text; 151 } 152 153 154 /** 155 * Gets the content for the info window and passes it to the specified callback - this allows for delayed loading (eg AJAX) as well as instant content 156 * @method 157 * @memberof WPGMZA.InfoWindow 158 * @return void 159 */ 160 WPGMZA.InfoWindow.prototype.getContent = function(callback) { 161 var html = ""; 162 var extra_html = ""; 163 164 if (this.feature instanceof WPGMZA.Marker) { 165 // Store locator distance away 166 // added by Nick 2020-01-12 167 if (this.feature.map.settings.store_locator_show_distance && this.feature.map.storeLocator && (this.feature.map.storeLocator.state == WPGMZA.StoreLocator.STATE_APPLIED)) { 168 var currentLatLng = this.feature.getPosition(); 169 var distance = this.workOutDistanceBetweenTwoMarkers(this.feature.map.storeLocator.center, currentLatLng); 170 171 extra_html += "<p>"+(this.feature.map.settings.store_locator_distance == WPGMZA.Distance.KILOMETERS ? distance + WPGMZA.localized_strings.kilometers_away : distance + " " + WPGMZA.localized_strings.miles_away)+"</p>"; 172 } 173 174 html = this.feature.address+extra_html; 175 } 176 177 if (this.contentHtml){ 178 html = this.contentHtml; 179 } 180 181 182 if(callback) 183 callback(html); 184 185 return html; 186 } 187 188 /** 189 * Opens the info window on the specified map, with the specified map object as the subject. 190 * @method 191 * @memberof WPGMZA.InfoWindow 192 * @param {WPGMZA.Map} map The map to open this InfoWindow on. 193 * @param {WPGMZA.Feature} feature The map object (eg marker, polygon) to open this InfoWindow on. 194 * @return boolean FALSE if the info window should not and will not open, TRUE if it will. This can be used by subclasses to establish whether or not the subclassed open should bail or open the window. 195 */ 196 WPGMZA.InfoWindow.prototype.open = function(map, feature) { 197 var self = this; 198 199 this.feature = feature; 200 201 if(WPGMZA.settings.disable_infowindows || WPGMZA.settings.wpgmza_settings_disable_infowindows == "1") 202 return false; 203 204 if(this.feature.disableInfoWindow) 205 return false; 206 207 this.state = WPGMZA.InfoWindow.STATE_OPEN; 208 209 return true; 210 } 211 212 /** 213 * Abstract function, closes this InfoWindow 214 * @method 215 * @memberof WPGMZA.InfoWindow 216 */ 217 WPGMZA.InfoWindow.prototype.close = function() 218 { 219 if(this.state == WPGMZA.InfoWindow.STATE_CLOSED) 220 return; 221 222 this.state = WPGMZA.InfoWindow.STATE_CLOSED; 223 this.trigger("infowindowclose"); 224 } 225 226 /** 227 * Abstract function, sets the content in this InfoWindow 228 * @method 229 * @memberof WPGMZA.InfoWindow 230 */ 231 WPGMZA.InfoWindow.prototype.setContent = function(options) 232 { 233 234 } 235 236 /** 237 * Abstract function, sets options on this InfoWindow 238 * @method 239 * @memberof WPGMZA.InfoWindow 240 */ 241 WPGMZA.InfoWindow.prototype.setOptions = function(options) 242 { 243 244 } 245 246 /** 247 * Event listener for when the map object is added. This will cause the info window to open if the map object has infoopen set 248 * @method 249 * @memberof WPGMZA.InfoWindow 250 * @return void 251 */ 252 WPGMZA.InfoWindow.prototype.onFeatureAdded = function() 253 { 254 if(this.feature.settings.infoopen == 1) 255 this.open(); 256 } 257 258 WPGMZA.InfoWindow.prototype.onOpen = function() 259 { 260 261 } 262 263 /** 264 * Gets a list of data attributes to be added to the info-window container 265 * 266 * These can be used for quick identification, or advanced styling from a structural perspective 267 * 268 * @return object 269 */ 270 WPGMZA.InfoWindow.prototype.getWrapperAttributes = function(){ 271 const attrs = { 272 type : 'system', 273 id : this.feature && this.feature.id ? this.feature.id : null, 274 feature : null 275 }; 276 277 if(this.feature){ 278 if(this.feature instanceof WPGMZA.Marker){ 279 attrs.feature = 'marker'; 280 } else if(this.feature instanceof WPGMZA.Polyline){ 281 attrs.feature = 'polyline'; 282 } else if(this.feature instanceof WPGMZA.Polygon){ 283 attrs.feature = 'polygon'; 284 } else if(this.feature instanceof WPGMZA.Circle){ 285 attrs.feature = 'circle'; 286 } else if(this.feature instanceof WPGMZA.Rectangle){
287 attrs.feature = 'rectangle'; 288 } 289 } 290 291 return attrs; 292 } 293 294 WPGMZA.InfoWindow.prototype.compileWrapperAttributes = function(){ 295 const attrs = this.getWrapperAttributes(); 296 297 const compiled = []; 298 for(let key in attrs){ 299 let value = attrs[key]; 300 if(key && value){ 301 compiled.push(`data-prop-${key}="${value}"`); 302 } 303 } 304 305 return compiled && compiled.length > 0 ? compiled.join(' ') : ''; 306 } 307 308 WPGMZA.InfoWindow.prototype.getStyleTypeClass = function(){ 309 return "wpgmza-infowindow-style-classic"; 310 } 311 312});
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.