1/** 2 * @namespace WPGMZA 3 * @module TileServerPreview 4 * @requires WPGMZA.EventDispatcher 5 */ 6jQuery(function($) { 7 WPGMZA.TileServerPreview = function(element, options){ 8 if(!(element instanceof HTMLSelectElement)) 9 throw new Error("Element is not an instance of HTMLSelectElement"); 10 11 this.element = $(element); 12 13 this.server = false; 14 15 this.wrap(); 16 this.bindEvents(); 17 this.update(); 18 } 19 20 WPGMZA.extend(WPGMZA.TileServerPreview, WPGMZA.EventDispatcher); 21 22 WPGMZA.TileServerPreview.createInstance = function(element) { 23 return new WPGMZA.TileServerPreview(element); 24 } 25 26 WPGMZA.TileServerPreview.prototype.wrap = function(){ 27 if(this.element){ 28 this.container = $("<div class='wpgmza-tile-server-preview-container' />"); 29 30 this.image = $("<img class='wpgmza-tile-server-preview-image' />"); 31 32 this.container.append(this.image); 33 34 this.element.parent().append(this.container); 35 this.container.append(this.element); 36 } 37 } 38 39 WPGMZA.TileServerPreview.prototype.bindEvents = function(){ 40 this.element.on('change', (event) => { 41 if(event.target){ 42 this.server = event.target.value; 43 this.update(); 44 } 45 }); 46 47 $(document.body).on('tileserverpreview.update.wpgmza', () => { 48 this.update(); 49 }) 50 51 this.element.trigger('change'); 52 } 53 54 WPGMZA.TileServerPreview.prototype.update = function(){ 55 this.container.removeClass('preview-ready'); 56 this.container.removeClass('preview-failed'); 57 58 this.container.find('.wpgmza-tile-server-preview-wrapper-multi').remove(); 59 60 if(this.container.is(":hidden")){ 61 /* Skip, no reason to update */ 62 return; 63 } 64 65 const definition = this.lookup(this.server); 66 if(definition){ 67 if(definition.multi){ 68 if(definition.layers && definition.layers.length){ 69 this.setImage(this.getPreview(definition.layers[0]), this.image, definition); 70 71 for(let i in definition.layers){ 72 if(i == 0){ 73 continue; 74 } 75 76 let layer = definition.layers[i]; 77 let secondaryImageWrapper = $("<div class='wpgmza-tile-server-preview-wrapper-multi' />"); 78 let secondaryImage = $("<img class='wpgmza-tile-server-preview-image' />"); 79 80 if(layer.dependencies){ 81 for(let dependency of layer.dependencies){ 82 let dependencyImage = $("<img class='wpgmza-tile-server-preview-image as-dependency' />"); 83 secondaryImageWrapper.append(dependencyImage); 84 85 this.setImage(this.getPreview(dependency), dependencyImage); 86 } 87 } 88 89 secondaryImageWrapper.append(secondaryImage); 90 this.container.append(secondaryImageWrapper); 91 92 this.setImage(this.getPreview(layer), secondaryImage); 93 } 94 95 } 96 } else { 97 if(definition.dependencies){ 98 for(let dependency of definition.dependencies){ 99 let dependencyImage = $("<img class='wpgmza-tile-server-preview-image as-dependency' />"); 100 101 this.setImage(this.getPreview(dependency), dependencyImage); 102 this.container.prepend(dependencyImage); 103 } 104 105 } 106 107 this.setImage(this.getPreview(definition), this.image, definition); 108 } 109 } else { 110 this.container.addClass('preview-failed').attr('data-am-label', (WPGMZA.localized_strings && WPGMZA.localized_strings.am_preview_fetch_failed) || 'Could not fetch preview'); 111 } 112 } 113 114 WPGMZA.TileServerPreview.prototype.lookup = function(server){ 115 if(this.element.find(`option[value="${server}"]`)){ 116 const data = this.element.find(`option[value="${server}"]`).data('tile-server-preview-config'); 117 return data; 118 } 119 return false;
120 } 121 122 WPGMZA.TileServerPreview.prototype.getPreview = function(data){ 123 if(data.url){ 124 let url = data.url; 125 url = decodeURI(url); 126 127 const authentication = {}; 128 if(data.key_required){ 129 authentication.name = data.key_field_name ? data.key_field_name : 'apikey', 130 authentication.token = this.getToken(); 131 } 132 133 let replacements = [ 134 { key : "{z}", "value" : 7 }, 135 { key : "{x}", "value" : 20 }, 136 { key : "{y}", "value" : 49 }, 137 { key : "{s}", "value" : "a" }, 138 { key : "{a-c}", "value" : "a" }, 139 ]; 140 141 let params = data.params ? data.params : {}; 142 if(authentication && authentication.name && authentication.token){ 143 if(url.indexOf('{' + authentication.name + '}') !== -1){ 144 replacements.push({key : "{" + authentication.name + "}", value : authentication.token}); 145 } else { 146 params[authentication.name] = authentication.token; 147 } 148 } 149 150 if(url.indexOf("{alias:") !== -1){ 151 url = url.replace(/{alias:.*?}/, ''); 152 } 153 154 let compiledParams = []; 155 for(let paramName in params){ 156 compiledParams.push(`${paramName}=${params[paramName]}`); 157 } 158 159 compiledParams = compiledParams.join("&"); 160 if(compiledParams){ 161 url = `${url}?${compiledParams}`; 162 } 163 164 for(let replacementKey in replacements){ 165 const replacement = replacements[replacementKey]; 166 url = url.replace(replacement.key, replacement.value); 167 } 168 return url; 169 } 170 return false; 171 } 172 173 WPGMZA.TileServerPreview.prototype.setImage = function(url, imageElement, definition){ 174 this.container.removeAttr('data-failed-fallback'); 175 if(url){ 176 const previewImage = new Image(); 177 previewImage.src = url; 178 previewImage.addEventListener('load', () => { 179 imageElement.attr('src', previewImage.src); 180 this.container.addClass('preview-ready'); 181 }); 182 183 previewImage.addEventListener('error', () => { 184 this.container.addClass('preview-failed').attr('data-am-label', (WPGMZA.localized_strings && WPGMZA.localized_strings.am_preview_fetch_failed) || 'Could not fetch preview'); 185 186 if(definition && definition instanceof Object){ 187 if(definition.type && definition.type === 'vector'){ 188 /* Preview on vectors will not work, so we will need to fallback to our local images */ 189 if(definition.label && definition.provider){ 190 let fallback = `${definition.provider}-${definition.label}`; 191 this.container.attr('data-failed-fallback', fallback.toLowerCase().replaceAll(' ', '-')); 192 } 193 } 194 } 195 }); 196 } else { 197 /* Failure */ 198 this.container.addClass('preview-failed').attr('data-am-label', (WPGMZA.localized_strings && WPGMZA.localized_strings.am_preview_fetch_failed) || 'Could not fetch preview'); 199 } 200 } 201 202 WPGMZA.TileServerPreview.prototype.getToken = function(){ 203 let engine = WPGMZA.settings ? WPGMZA.settings.engine : false; 204 205 if($('[name="wpgmza_maps_engine"]:checked').length){ 206 if($('[name="wpgmza_maps_engine"]:checked').val() !== engine){ 207 engine = $('[name="wpgmza_maps_engine"]:checked').val(); 208 } 209 } 210 211 if(engine){ 212 let tokenFieldName = false; 213 let token = false; 214 switch(engine){ 215 case 'open-layer': 216 case 'open-layer-latest': 217 tokenFieldName = 'open_layers_api_key'; 218 break; 219 case 'leaflet': 220 tokenFieldName = 'leaflet_api_key'; 221 break; 222 case 'leaflet-azure': 223 tokenFieldName = 'wpgmza_leaflet_azure_key'; 224 break; 225 case 'leaflet-stadia': 226 tokenFieldName = 'wpgmza_leaflet_stadia_key'; 227 break; 228 case 'leaflet-maptiler': 229 tokenFieldName = 'wpgmza_leaflet_maptiler_key'; 230 break; 231 case 'leaflet-locationiq': 232 tokenFieldName = 'wpgmza_leaflet_locationiq_key'; 233 break; 234 } 235 236 if(WPGMZA.settings && WPGMZA.settings[tokenFieldName]){ 237 token = WPGMZA.settings[tokenFieldName]; 238 } 239 240 if($('[name="' + tokenFieldName + '"]').length){ 241 if($('[name="' + tokenFieldName + '"]').val() !== token){ 242 token = $('[name="' + tokenFieldName + '"]').val(); 243 } 244 } 245 246 return token; 247 } 248 return false;
249 } 250 251 $(document.body).ready(function(){ 252 $("select.wpgmza-tile-server-preview").each(function(index, el) { 253 el.wpgmzaTileServerPreview = WPGMZA.TileServerPreview.createInstance(el); 254 }); 255 }); 256 257});
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.