1/** 2 * @namespace WPGMZA 3 * @module MapEditPage 4 * @requires WPGMZA.EventDispatcher 5 */ 6 7var wpgmza_autoCompleteDisabled = false; 8 9jQuery(function($) { 10 11 if(WPGMZA.currentPage != "map-edit") 12 return; 13 14 WPGMZA.MapEditPage = function() 15 { 16 var self = this; 17 var element = document.body; 18 19 WPGMZA.EventDispatcher.call(this); 20 21 if(!WPGMZA.settings.internalEngine || WPGMZA.InternalEngine.isLegacy()){ 22 // Only force this if we are in legacy 23 // New internal engines will handle this internally instead 24 $("#wpgmaps_options fieldset").wrapInner("<div class='wpgmza-flex'></div>"); 25 } 26 27 this.themePanel = new WPGMZA.ThemePanel(); 28 this.themeEditor = new WPGMZA.ThemeEditor(); 29 this.tilesetPanel = new WPGMZA.TilesetPanel(); 30 31 this.sidebarGroupings = new WPGMZA.SidebarGroupings(); 32 33 this.map = WPGMZA.maps[0]; 34 35 // Drawing manager 36 if(!WPGMZA.pro_version || WPGMZA.Version.compare(WPGMZA.pro_version, '8.1.0') >= WPGMZA.Version.EQUAL_TO) 37 this.drawingManager = WPGMZA.DrawingManager.createInstance(this.map); 38 39 // UI 40 this.initDataTables(); 41 this.initFeaturePanels(); 42 this.initJQueryUIControls(); 43 44 if(WPGMZA.locale !== 'en'){ 45 if(WPGMZA.InternalEngine.isLegacy()){ 46 $('#datatable_no_result_message,#datatable_search_string').parent().parent().hide(); 47 } else { 48 $('#datatable_no_result_message,#datatable_search_string').parent().hide(); 49 } 50 } 51 52 // Address input 53 $("input.wpgmza-address").each(function(index, el) { 54 el.addressInput = WPGMZA.AddressInput.createInstance(el, self.map); 55 }); 56 57 $('#wpgmza-map-edit-page input[type="color"]').each(function(){ 58 var buttonClass = WPGMZA.InternalEngine.isLegacy() ? 'button-secondary' : 'wpgmza-button'; 59 $("<div class='" + buttonClass + " wpgmza-paste-color-btn' title='Paste a HEX color code'><i class='fa fa-clipboard' aria-hidden='true'></i></div>").insertAfter(this); 60 }); 61 62 63 jQuery('body').on('click','.wpgmza_ac_result', function(e) { 64 var index = jQuery(this).data('id'); 65 var lat = jQuery(this).data('lat'); 66 var lng = jQuery(this).data('lng'); 67 var name = jQuery('#wpgmza_item_address_'+index).html(); 68 69 70 jQuery("input[name='lat']").val(lat); 71 jQuery("input[name='lng']").val(lng); 72 jQuery("#wpgmza_add_address_map_editor").val(name); 73 jQuery('#wpgmza_autocomplete_search_results').hide(); 74 }); 75 76 jQuery('body').on('click', '.wpgmza-paste-color-btn', function(){ 77 try{ 78 var colorBtn = $(this); 79 if(!navigator || !navigator.clipboard || !navigator.clipboard.readText){ 80 return; 81 } 82 83 navigator.clipboard.readText() 84 .then(function(textcopy) { 85 colorBtn.parent().find('input[type="color"]').val("#" + textcopy.replace("#","").trim()); 86 }) 87 .catch(function(err) { 88 console.error("WP Go Maps: Could not access clipboard", err); 89 }); 90 91 } catch(c_ex){ 92 93 } 94 }); 95 96 jQuery('body').on('focusout', '#wpgmza_add_address_map_editor', function(e) { 97 setTimeout(function() { 98 jQuery('#wpgmza_autocomplete_search_results').fadeOut('slow'); 99 },500) 100 101 }); 102 103 $(document).on('heartbeat-tick', (event, response, status, jqXHR) => { 104 try{ 105 if(response && response.nonces_expired){ 106 if(response.wpgmza_nonce){ 107 /* The hearbeat sent back a new nonce which should replace the map editor nonce */ 108 $('form[name="wpgmza_map_form"] input[name="nonce"]').val(response.wpgmza_nonce).trigger('change'); 109 } 110 } 111 } catch (ex){ 112 /* Ignore, we can't handle this data */ 113 } 114 115 }); 116 117 var ajaxRequest = false; 118 var wpgmzaAjaxTimeout = false; 119 120 var wpgmzaStartTyping = false; 121 var wpgmzaKeyStrokeCount = 1; 122 var wpgmzaAvgTimeBetweenStrokes = 300; //300 ms by default (equates to 40wpm which is the average typing speed of a person) 123 var wpgmzaTotalTimeForKeyStrokes = 0; 124 var wpgmzaTmp = ''; 125 var wpgmzaIdentifiedTypingSpeed = false; 126 127 $('body').on('keypress', '.wpgmza-address', function(e) { 128 if(self.shouldAddressFieldUseEnhancedAutocomplete(this)){ 129 self.onKeyUpEnhancedAutocomplete(e, this); 130 } 131 }); 132 133 134 // Map height change (for warning) 135 $("#wpgmza_map_height_type").on("change", function(event) { 136 self.onMapHeightTypeChange(event); 137 }); 138 139 // Don't have instructions in advanced marker panel, it's confusing for debugging and unnecessary 140 $("#advanced-markers .wpgmza-feature-drawing-instructions").remove(); 141
142 // Hide the auto search area maximum zoom - not available in Basic. Pro will take care of showing it when needed 143 $("[data-search-area='auto']").hide(); 144 145 // Control listeners 146 $(document.body).on("click", "[data-wpgmza-admin-marker-datatable] input[name='mark']", function(event) { 147 self.onShiftClick(event); 148 }); 149 150 $("#wpgmza_map_type").on("change", function(event) { 151 self.onMapTypeChanged(event); 152 }); 153 154 $("body").on("click",".wpgmza_copy_shortcode", function() { 155 var $temp = jQuery('<input>'); 156 var $tmp2 = jQuery('<span id="wpgmza_tmp" style="display:none; width:100%; text-align:center;">'); 157 jQuery("body").append($temp); 158 $temp.val(jQuery(this).val()).select(); 159 document.execCommand("copy"); 160 $temp.remove(); 161 WPGMZA.notification("Shortcode Copied", false, '.action-bar', 'top-left'); 162 }); 163 164 this.on("markerupdated", function(event) { 165 self.onMarkerUpdated(event); 166 }); 167 168 // NB: Older version of Pro (< 7.0.0 - pre-WPGMZA.Map) will have this.map as undefined. Only run this code if we have a WPGMZA.Map to work with. 169 if(this.map) 170 { 171 this.map.on("zoomchanged", function(event) { 172 self.onZoomChanged(event); 173 }); 174 175 this.map.on("boundschanged", function(event) { 176 self.onBoundsChanged(event); 177 }); 178 179 this.map.on("rightclick", function(event) { 180 self.onRightClick(event); 181 }); 182 } 183 184 $(element).on("click", ".wpgmza_poly_del_btn", function(event) { 185 self.onDeletePolygon(event); 186 }); 187 188 $(element).on("click", ".wpgmza_polyline_del_btn", function(event) { 189 self.onDeletePolyline(event); 190 }); 191 192 $(element).on("click", ".wpgmza_dataset_del_btn", function(evevnt) { 193 self.onDeleteHeatmap(event); 194 }); 195 196 $(element).on("click", ".wpgmza_circle_del_btn", function(event) { 197 self.onDeleteCircle(event); 198 }); 199 200 $(element).on("click", ".wpgmza_rectangle_del_btn", function(event) { 201 self.onDeleteRectangle(event); 202 }); 203 204 $(element).on("click", "#wpgmza-open-advanced-theme-data", function(event){ 205 event.preventDefault(); 206 $('.wpgmza_theme_data_container').toggleClass('wpgmza_hidden'); 207 }); 208 209 $(element).on("click", ".wpgmza-shortcode-button", function(event){ 210 event.preventDefault(); 211 $(element).find('.wpgmza-shortcode-description').addClass('wpgmza-hidden'); 212 213 const nearestRow = $(this).closest('.wpgmza-row'); 214 if(nearestRow.length){ 215 const nearestHint = nearestRow.next('.wpgmza-shortcode-description'); 216 if(nearestHint.length){ 217 nearestHint.removeClass('wpgmza-hidden'); 218 } 219 } 220 221 const shortcode = $(this).text(); 222 if(shortcode.length){ 223 const temp = jQuery('<input>'); 224 $(document.body).append(temp); 225 temp.val(shortcode).select(); 226 document.execCommand("copy"); 227 temp.remove(); 228 WPGMZA.notification("Shortcode Copied", false, '.grouping.open[data-group="map-settings-shortcodes"]', 'top-right'); 229 230 } 231 }); 232 233 /* One time hints */ 234 $(document.body).find('.wpgmza-one-time-hint').each((index, hint) => { 235 const delay = $(hint).data('hint-delay'); 236 if(delay){ 237 setTimeout(() => { 238 $(hint).addClass('show-hint'); 239 240 setTimeout(() => { 241 $(hint).remove(); 242 }, parseInt(delay) * 1000); 243 }, parseInt(delay) * 1000); 244 } 245 }); 246 247 /* Map Engine Toolbar */ 248 if($(document.body).find('.wpgmza-engine-switch-toolbar').length > 0){ 249 $(document.body).find('.wpgmza-engine-switch-toolbar .wpgmza-button[data-engine-switch-control]').on('click', function(event){ 250 const engineSwitchControl = $(this).attr('data-engine-switch-control'); 251 if(engineSwitchControl === 'apply'){ 252 /* Apply the new engine, via Ajax and then save this map to show it */ 253 $.ajax(WPGMZA.ajaxurl, { 254 method: "POST", 255 data : { 256 action : 'wpgmza_persisten_notice_quick_action', 257 relay : 'swap_map_engine_from_toolbar', 258 map_engine : $(document.body).find('.wpgmza-engine-switch-toolbar select').val(), 259 wpgmza_security : WPGMZA.ajaxnonce 260 }, 261 success : function(response){ 262 /* Save the map for good measure */ 263 $('input[name="wpgmza_savemap"]').click(); 264 }, 265 error: function(){} 266 });
267 } else if(engineSwitchControl === 'dismiss'){ 268 /* Dismiss this toolbar - It will never show again */ 269 $(document.body).find('.wpgmza-engine-switch-toolbar').hide(); 270 271 $.ajax(WPGMZA.ajaxurl, { 272 method: "POST", 273 data : { 274 action : 'wpgmza_persisten_notice_quick_action', 275 relay : 'swap_map_engine_from_toolbar_dismiss', 276 wpgmza_security : WPGMZA.ajaxnonce 277 }, 278 success : function(response){ 279 280 }, 281 error: function(){} 282 }); 283 } 284 }); 285 } 286 287 this.initZoomSliderPreviews(); 288 } 289 290 WPGMZA.extend(WPGMZA.MapEditPage, WPGMZA.EventDispatcher); 291 292 WPGMZA.MapEditPage.createInstance = function() 293 { 294 if(WPGMZA.isProVersion() && WPGMZA.Version.compare(WPGMZA.pro_version, "8.0.0") >= WPGMZA.Version.EQUAL_TO) 295 return new WPGMZA.ProMapEditPage(); 296 297 return new WPGMZA.MapEditPage(); 298 } 299 300 WPGMZA.MapEditPage.prototype.initDataTables = function() 301 { 302 var self = this; 303 304 $("[data-wpgmza-datatable][data-wpgmza-rest-api-route]").each(function(index, el) { 305 306 var featureType = $(el).attr("data-wpgmza-feature-type"); 307 308 self[featureType + "AdminDataTable"] = new WPGMZA.AdminFeatureDataTable(el); 309 310 }); 311 } 312 313 WPGMZA.MapEditPage.prototype.initFeaturePanels = function() 314 { 315 var self = this; 316 317 $(".wpgmza-feature-accordion[data-wpgmza-feature-type]").each(function(index, el) { 318 319 var featurePanelElement = $(el).find(".wpgmza-feature-panel-container > *"); 320 var featureType = $(el).attr("data-wpgmza-feature-type"); 321 var panelClassName = WPGMZA.capitalizeWords(featureType) + "Panel"; 322 var module = WPGMZA[panelClassName]; 323 var instance = module.createInstance(featurePanelElement, self); 324 325 self[featureType + "Panel"] = instance; 326 327 }); 328 } 329 330 WPGMZA.MapEditPage.prototype.initJQueryUIControls = function() 331 { 332 var self = this; 333 var mapContainer; 334 335 // Now initialise tabs 336 $("#wpgmaps_tabs").tabs(); 337 338 // NB: If the map container has a <ul> then this will break the tabs (this happens in OpenLayers). Temporarily detach the map to avoid this. 339 mapContainer = $("#wpgmza-map-container").detach(); 340 341 $("#wpgmaps_tabs_markers").tabs(); 342 343 // NB: Re-add the map container (see above) 344 $(".map_wrapper").prepend(mapContainer); 345 346 // And the zoom slider 347 $("#slider-range-max").slider({ 348 range: "max", 349 min: 1, 350 max: 22, 351 value: $("input[name='map_start_zoom']").val(), 352 slide: function( event, ui ) { 353 $("input[name='map_start_zoom']").val(ui.value); 354 self.map.setZoom(ui.value); 355 356 $("input[name='map_start_zoom']").parent().find('[data-zoom-hint]').text(`${ui.value}`); 357 }, 358 create: function(event, ui) { 359 $("input[name='map_start_zoom']").parent().find('[data-zoom-hint]').text($("input[name='map_start_zoom']").val()); 360 } 361 }); 362 363 364 /* Mobile override zoom level slider */ 365 $('#zoom_level_mobile_override_enabled').on('change', function(){ 366 if($(this).prop('checked')){ 367 $('#zoom_level_mobile_override_level').fadeIn(); 368 }else{ 369 $('#zoom_level_mobile_override_level').fadeOut(); 370 } 371 }); 372 373 $('#zoom_level_mobile_override_enabled').trigger('change'); 374 375 $("#zoom-level-mobile-override-slider").slider({ 376 range: "max", 377 min: 1, 378 max: 22, 379 value: $("input[name='zoom_level_mobile_override']").val(), 380 slide: function( event, ui ) { 381 $("input[name='zoom_level_mobile_override']").val(ui.value); 382 383 $("input[name='zoom_level_mobile_override']").parent().find('[data-zoom-hint]').text(`${ui.value}`); 384 }, 385 create: function(event, ui) { 386 $("input[name='zoom_level_mobile_override']").parent().find('[data-zoom-hint]').text($("input[name='zoom_level_mobile_override']").val()); 387 } 388 }); 389 390 /* Mobile override dimensions */ 391 $('#map_dimensions_mobile_override_enabled').on('change', function(){ 392 if($(this).prop('checked')){ 393 $('.wpgmza-map-mobile-dimension-override').fadeIn(); 394 }else{ 395 $('.wpgmza-map-mobile-dimension-override').fadeOut(); 396 } 397 }); 398 399 $('#map_dimensions_mobile_override_enabled').trigger('change'); 400 } 401 402 WPGMZA.MapEditPage.prototype.onShiftClick = function(event) 403 { 404 var checkbox = event.currentTarget; 405 var row = jQuery(checkbox).closest("tr"); 406 407 if(this.lastSelectedRow && event.shiftKey) 408 { 409 var prevIndex = this.lastSelectedRow.index(); 410 var currIndex = row.index(); 411 var startIndex = Math.min(prevIndex, currIndex); 412 var endIndex = Math.max(prevIndex, currIndex); 413 var rows = jQuery("[data-wpgmza-admin-marker-datatable] tbody>tr"); 414 415 // Clear 416 jQuery("[data-wpgmza-admin-marker-datatable] input[name='mark']").prop("checked", false); 417 418 for(var i = startIndex; i <= endIndex; i++) 419 jQuery(rows[i]).find("input[name='mark']").prop("checked", true); 420 421 422 423 } 424 425 this.lastSelectedRow = row; 426 } 427 428 WPGMZA.MapEditPage.prototype.onMapTypeChanged = function(event) 429 { 430 if(WPGMZA.settings.engine != "google-maps"){ 431 if(this.map.setMapType){ 432 this.map.setMapType($(event.target).find('option[value="' + event.target.value + '"]').data('map-type')); 433 } 434 return; 435 } 436 437 var mapTypeId;
438 439 switch(event.target.value) 440 { 441 case "2": 442 mapTypeId = google.maps.MapTypeId.SATELLITE; 443 break; 444 445 case "3": 446 mapTypeId = google.maps.MapTypeId.HYBRID; 447 break; 448 449 case "4": 450 mapTypeId = google.maps.MapTypeId.TERRAIN; 451 break; 452 453 default: 454 mapTypeId = google.maps.MapTypeId.ROADMAP; 455 break; 456 } 457 458 this.map.setOptions({ 459 mapTypeId: mapTypeId 460 }); 461 } 462 463 WPGMZA.MapEditPage.prototype.onMarkerUpdated = function(event) 464 { 465 this.markerDataTable.reload(); 466 } 467 468 WPGMZA.MapEditPage.prototype.onZoomChanged = function(event) { 469 $(".map_start_zoom").val(this.map.getZoom()); 470 } 471 472 WPGMZA.MapEditPage.prototype.onBoundsChanged = function(event) 473 { 474 var location = this.map.getCenter(); 475 476 $("#wpgmza_start_location").val(location.lat + "," + location.lng); 477 $("input[name='map_start_lat']").val(location.lat); 478 $("input[name='map_start_lng']").val(location.lng); 479 480 $("#wpgmza_start_zoom").val(this.map.getZoom()); 481 482 $("#wpgmaps_save_reminder").show(); 483 } 484 485 WPGMZA.MapEditPage.prototype.onMapHeightTypeChange = function(event) { 486 if(event.target.value == "%") 487 $("#wpgmza_height_warning").show(); 488 } 489 490 WPGMZA.MapEditPage.prototype.onRightClick = function(event) { 491 var self = this; 492 var marker; 493 494 if(!WPGMZA.InternalEngine.isLegacy() && this.sidebarGroupings){ 495 /* Context menu delegates */ 496 if(this.sidebarGroupings.canOpenContextMenu()){ 497 if(this.sidebarGroupings.openContextMenu(event)){ 498 /* Context menu did open */ 499 return; 500 } 501 } 502 503 if(this.sidebarGroupings.isOpen('global') || this.sidebarGroupings.isOpen('map-markers')){ 504 /* Either their on the root tab, or they are on the marker list, so let's open the marker creator for them */ 505 this.sidebarGroupings.openTabByFeatureType('marker'); 506 } 507 } 508 509 if(this.drawingManager && this.drawingManager.mode != WPGMZA.DrawingManager.MODE_MARKER) 510 return; // Do nothing, not in marker mode 511 512 if(!this.rightClickMarker) 513 { 514 this.rightClickMarker = WPGMZA.Marker.createInstance({ 515 draggable: true, 516 }); 517 518 this.rightClickMarker.on("dragend", function(event) { 519 $(".wpgmza-marker-panel [data-ajax-name='address']").val(event.latLng.lat + ", " + event.latLng.lng); 520 }); 521 522 this.map.on("click", function(event) { 523 /* Remove the marker on left click*/ 524 self.rightClickMarker.setMap(null); 525 526 /* Seeing as we are removing the marker, clear the lat/lng combo as well */ 527 $(".wpgmza-marker-panel [data-ajax-name='address']").val(""); 528 }); 529 } 530 531 marker = this.rightClickMarker; 532 533 marker.setPosition(event.latLng); 534 marker.setMap(this.map); 535 536 $(".wpgmza-marker-panel [data-ajax-name='address']").val(event.latLng.lat+', '+event.latLng.lng); 537 } 538 539 WPGMZA.MapEditPage.prototype.onDeletePolygon = function(event) 540 { 541 var cur_id = parseInt($(this).attr("id")); 542 var data = { 543 action: 'delete_poly', 544 security: wpgmza_legacy_map_edit_page_vars.ajax_nonce, 545 map_id: this.map.id, 546 poly_id: cur_id 547 }; 548 549 $.post(ajaxurl, data, function (response) { 550 551 WPGM_Path[cur_id].setMap(null); 552 delete WPGM_PathData[cur_id]; 553 delete WPGM_Path[cur_id]; 554 $("#wpgmza_poly_holder").html(response); 555 556 }); 557 } 558 559 WPGMZA.MapEditPage.prototype.onDeletePolyline = function(event) 560 { 561 var cur_id = $(this).attr("id"); 562 var data = { 563 action: 'delete_polyline', 564 security: wpgmza_legacy_map_edit_page_vars.ajax_nonce, 565 map_id: this.map.id, 566 poly_id: cur_id 567 }; 568 569 $.post(ajaxurl, data, function (response) { 570 571 WPGM_PathLine[cur_id].setMap(null); 572 delete WPGM_PathLineData[cur_id]; 573 delete WPGM_PathLine[cur_id]; 574 $("#wpgmza_polyline_holder").html(response); 575 576 }); 577 } 578 579 WPGMZA.MapEditPage.prototype.onDeleteHeatmap = function(event) 580 { 581 var cur_id = $(this).attr("id"); 582 var data = { 583 action: 'delete_dataset', 584 security: wpgmza_legacy_map_edit_page_vars.ajax_nonce, 585 map_id: this.map.id, 586 poly_id: cur_id 587 }; 588 589 $.post(ajaxurl, data, function (response) { 590
591 heatmap[cur_id].setMap(null); 592 delete heatmap[cur_id]; 593 $("#wpgmza_heatmap_holder").html(response); 594 595 }); 596 } 597 598 WPGMZA.MapEditPage.prototype.onDeleteCircle = function(event) 599 { 600 var circle_id = $(this).attr("id"); 601 602 var data = { 603 action: 'delete_circle', 604 security: wpgmza_legacy_map_edit_page_vars.ajax_nonce, 605 map_id: this.map.id, 606 circle_id: circle_id 607 }; 608 609 $.post(ajaxurl, data, function (response) { 610 611 $("#tabs-m-5 table").replaceWith(response); 612 613 circle_array.forEach(function (circle) { 614 615 if (circle.id == circle_id) { 616 circle.setMap(null); 617 return false; 618 } 619 620 }); 621 622 }); 623 } 624 625 WPGMZA.MapEditPage.prototype.onDeleteRectangle = function(event) 626 { 627 var rectangle_id = $(this).attr("id"); 628 629 var data = { 630 action: 'delete_rectangle', 631 security: wpgmza_legacy_map_edit_page_vars.ajax_nonce, 632 map_id: this.map.id, 633 rectangle_id: rectangle_id 634 }; 635 636 $.post(ajaxurl, data, function (response) { 637 638 $("#tabs-m-6 table").replaceWith(response); 639 640 rectangle_array.forEach(function (rectangle) { 641 642 if (rectangle.id == rectangle_id) { 643 rectangle.setMap(null); 644 return false; 645 } 646 647 }); 648 649 }); 650 } 651 652 WPGMZA.MapEditPage.prototype.shouldAddressFieldUseEnhancedAutocomplete = function(element){ 653 /* This should really be moved to its own module later (EnhancedAutocomplete) */ 654 if(element && element.id && element.id === 'wpgmza_add_address_map_editor'){ 655 return true; 656 } 657 return false; 658 } 659 660 WPGMZA.MapEditPage.prototype.onKeyUpEnhancedAutocomplete = function(event, element){ 661 /* This should really be moved to its own module later (EnhancedAutocomplete) */ 662 if(element._wpgmzaAddressInput && element._wpgmzaAddressInput.wpgmzaAutocomplete && element._wpgmzaAddressInput.wpgmzaAutocomplete.isReady()){ 663 /* At some point the system swapped over to the Google Autocomplete, we should not take further action here */ 664 return; 665 } 666 667 if(!element._wpgmzaEnhancedAutocomplete){ 668 /* 669 * Set up some default state trackers 670 * 671 * Some notes, 300ms for avg keystroke equates to 40wpm, which is the average typing speed of a person 672 */ 673 element._wpgmzaEnhancedAutocomplete = { 674 identifiedTypingSpeed : false, 675 typingTimeout : false, 676 startTyping : false, 677 keyStrokeCount : 1, 678 avgTimeBetweenStrokes : 300, 679 totalTimeForKeyStrokes : 0, 680 ajaxRequest : false, 681 ajaxTimeout : false, 682 requestErrorCount : 0, 683 disabledFlag : false, 684 disabledCheckCount : 0 685 }; 686 } 687 688 let enhancedAutocomplete = element._wpgmzaEnhancedAutocomplete; 689 690 const ignoredKeys = [ 691 "Escape", "Alt", "Control", "Option", "Shift", 692 "ArrowLeft", "ArrowRight", "ArrowUp", "ArrowDown" 693 ]; 694 695 if(ignoredKeys.indexOf(event.key) !== -1){ 696 /* This keystroke should be ignored */ 697 $('#wpgmza_autocomplete_search_results').hide(); 698 return; 699 } 700 701 if(enhancedAutocomplete.disabledFlag){ 702 /* The server has disabled autocomplete requests manually */ 703 enhancedAutocomplete.disabledCheckCount ++; 704 if(enhancedAutocomplete.disabledCheckCount >= 5){ 705 /* User keeps trying to use te autocomplete, even though server has reported this as disabled */ 706 /* Swap out to Google now, because this is silly */ 707 this.swapEnhancedAutocomplete(element); 708 } 709 return; 710 } 711 712 let googleApiKey = false; 713 if(WPGMZA.settings && (WPGMZA.settings.googleMapsApiKey || WPGMZA.settings.wpgmza_google_maps_api_key)){ 714 googleApiKey = WPGMZA.settings.googleMapsApiKey ? WPGMZA.settings.googleMapsApiKey : WPGMZA.settings.wpgmza_google_maps_api_key; 715 } 716 717 if(!enhancedAutocomplete.identifiedTypingSpeed){ 718 let d = new Date(); 719 if(enhancedAutocomplete.typingTimeout){ 720 clearTimeout(enhancedAutocomplete.typingTimeout); 721 } 722 723 enhancedAutocomplete.typingTimeout = setTimeout(() => { 724 enhancedAutocomplete.startTyping = false; 725 enhancedAutocomplete.avgTimeBetweenStrokes = 300; 726 enhancedAutocomplete.totalTimeForKeyStrokes = 0; 727 }, 1500); 728 729 if(!enhancedAutocomplete.startTyping){ 730 enhancedAutocomplete.startTyping = d.getTime(); 731 enhancedAutocomplete.keyStrokeCount ++; 732 } else { 733 if(enhancedAutocomplete.keyStrokeCount > 1){ 734 enhancedAutocomplete.currentTimeBetweenStrokes = d.getTime() - enhancedAutocomplete.startTyping; 735 enhancedAutocomplete.totalTimeForKeyStrokes += enhancedAutocomplete.currentTimeBetweenStrokes; 736 737 enhancedAutocomplete.avgTimeBetweenStrokes = (enhancedAutocomplete.totalTimeForKeyStrokes / (enhancedAutocomplete.keyStrokeCount - 1)); 738 enhancedAutocomplete.startTyping = d.getTime(); 739 740 if(enhancedAutocomplete.keyStrokeCount >= 3){ 741 /* We only need to measure speed based on the first 3 strokes */ 742 enhancedAutocomplete.identifiedTypingSpeed = enhancedAutocomplete.avgTimeBetweenStrokes; 743 } 744 } 745 746 enhancedAutocomplete.keyStrokeCount ++; 747 } 748 749 /* Bail while we take our measurements, should be the first 3 characters */ 750 return; 751 } 752 753 /* Continue processing this request, we have at this stage, determined the users typing speed and we are ready to roll */ 754 if(enhancedAutocomplete.ajaxTimeout){ 755 clearTimeout(enhancedAutocomplete.ajaxTimeout); 756 } 757 758 /* Show the searching stub */ 759 $('#wpgmza_autocomplete_search_results').html('<div class="wpgmza-pad-5">Searching...</div>'); 760 $('#wpgmza_autocomplete_search_results').show(); 761 762 enhancedAutocomplete.currentSearch = $(element).val(); 763 if(enhancedAutocomplete.currentSearch && enhancedAutocomplete.currentSearch.trim().length > 0){ 764 /* Check if we are in the middle of a request, if so, let's abore that to do focus on the new one instead */ 765 if(enhancedAutocomplete.ajaxRequest !== false){ 766 enhancedAutocomplete.ajaxRequest.abort(); 767 } 768
769 enhancedAutocomplete.requestParams = { 770 domain : window.location.hostname 771 }; 772 773 if(enhancedAutocomplete.requestParams.domain === 'localhost'){ 774 try { 775 /* 776 * Local domains sometimes run into issues with the enhanced autocomplete. 777 * 778 * To ensure new users get the most out of the free service, let's go ahead and prepare a local style request 779 */ 780 let paths = window.location.pathname.match(/\/(.*?)\//); 781 if(paths && paths.length >= 2 && paths[1]){ 782 let path = paths[1]; 783 enhancedAutocomplete.requestParams.domain += "-" + path; 784 } 785 } catch (ex){ 786 /* Leave it alone */ 787 } 788 } 789 790 enhancedAutocomplete.requestParams.url = "https://wpgmaps.us-3.evennode.com/api/v1/autocomplete"; 791 792 enhancedAutocomplete.requestParams.query = { 793 s : enhancedAutocomplete.currentSearch, 794 d : enhancedAutocomplete.requestParams.domain, 795 hash : WPGMZA.siteHash 796 }; 797 798 if(googleApiKey){ 799 /* Send through the google key for further enhancements */ 800 enhancedAutocomplete.requestParams.query.k = googleApiKey; 801 } 802 803 if(WPGMZA.settings){ 804 if(WPGMZA.settings.engine){ 805 enhancedAutocomplete.requestParams.query.engine = WPGMZA.settings.engine; 806 } 807 808 if(WPGMZA.settings.internal_engine){ 809 enhancedAutocomplete.requestParams.query.build = WPGMZA.settings.internal_engine; 810 } 811 } 812 813 /* Finalize the enhanced autocomplete URL query */ 814 enhancedAutocomplete.requestParams.query = new URLSearchParams(enhancedAutocomplete.requestParams.query); 815 enhancedAutocomplete.requestParams.url += "?" + enhancedAutocomplete.requestParams.query.toString(); 816 817 /* Place request in a timetout, to delay the send time by the typing speed */ 818 enhancedAutocomplete.ajaxTimeout = setTimeout(() => { 819 /* Prepare and send the request */ 820 enhancedAutocomplete.ajaxRequest = $.ajax({ 821 url : enhancedAutocomplete.requestParams.url, 822 type : 'GET', 823 dataType : 'json', 824 success : (results) => { 825 try { 826 if(results instanceof Object){ 827 if(results.error){ 828 /* We have an error, we need to work with this */ 829 if (results.error == 'error1') { 830 this.swapEnhancedAutocomplete(element); 831 if(!element._wpgmzaAddressInput || !element._wpgmzaAddressInput.wpgmzaAutocomplete.isReady()){ 832 $('#wpgmza_autoc_disabled').html(WPGMZA.localized_strings.cloud_api_key_error_1); 833 $('#wpgmza_autoc_disabled').fadeIn('slow'); 834 835 } 836 837 $('#wpgmza_autocomplete_search_results').hide(); 838 enhancedAutocomplete.disabledFlag = true; 839 } else { 840 /* General request error was reached, we need to report it and instantly swap back to Google */ 841 console.warn("Enhanced Autocomplete Error: " + results.error + " (Switching to internal)"); 842 this.swapEnhancedAutocomplete(element); 843 } 844 } else { 845 /* Things are looking good, let's serve the data */ 846 $('#wpgmza_autocomplete_search_results').html(''); 847 let html = ""; 848 849 for(var i in results){ 850 html += "<div class='wpgmza_ac_result " + (html === "" ? "" : "border-top") + "' data-id='" + i + "' data-lat='"+results[i]['lat']+"' data-lng='"+results[i]['lng']+"'><div class='wpgmza_ac_container'><div class='wpgmza_ac_icon'><img src='"+results[i]['icon']+"' /></div><div class='wpgmza_ac_item'><span id='wpgmza_item_name_"+i+"' class='wpgmza_item_name'>" + results[i]['place_name'] + "</span><span id='wpgmza_item_address_"+i+"' class='wpgmza_item_address'>" + results[i]['formatted_address'] + "</span></div></div></div>"; 851 } 852 853 if(!html || html.length <= 0){ 854 html = "<div class='p-2 text-center'><small>No results found...</small></div>"; 855 } 856 857 $('#wpgmza_autocomplete_search_results').html(html); 858 $('#wpgmza_autocomplete_search_results').show(); 859 860 /* Finally reset all error counters */ 861 enhancedAutocomplete.disabledCheckCount = 0; 862 enhancedAutocomplete.requestErrorCount = 0; 863 } 864 } else { 865 /* Results are malformed - Swap out now */ 866 this.swapEnhancedAutocomplete(element); 867 } 868 } catch (ex){ 869 /* Results are malformed - Swap out now */ 870 console.error("WP Go Maps Plugin: There was an error returning the list of places for your search"); 871 this.swapEnhancedAutocomplete(element); 872 } 873 }, 874 error : () => { 875 /* Request failed */ 876 $('#wpgmza_autocomplete_search_results').hide(); 877 878 /* There is a chance that this was purely a network issue, we should count it, and bail later if need be */ 879 enhancedAutocomplete.requestErrorCount ++; 880 if(enhancedAutocomplete.requestErrorCount >= 3){ 881 /* Swap out now */ 882 this.swapEnhancedAutocomplete(element); 883 } 884 } 885 }); 886 }, (enhancedAutocomplete.identifiedTypingSpeed * 2)); 887 } else { 888 /* Search is empty, just hide the popup for now */ 889 $('#wpgmza_autocomplete_search_results').hide(); 890 } 891 892 } 893 894 WPGMZA.MapEditPage.prototype.swapEnhancedAutocomplete = function(element){ 895 /* Disable the enhanced autocomplete, and swap back to the native systems instead */ 896 if(element._wpgmzaAddressInput){ 897 if(!element._wpgmzaAddressInput.wpgmzaAutocomplete.isReady()){ 898 element._wpgmzaAddressInput.wpgmzaAutocomplete.autoload(); 899 900 if(element._wpgmzaAddressInput.wpgmzaAutocomplete){ 901 element._wpgmzaAddressInput.wpgmzaAutocomplete.find(); 902 } 903 } 904 } 905 906 $('#wpgmza_autocomplete_search_results').hide(); 907 $('#wpgmza_autoc_disabled').hide(); 908 } 909 910 WPGMZA.MapEditPage.prototype.initZoomSliderPreviews = function(){ 911 this._zoomPreviewState = { 912 type : false, 913 revert : false, 914 input : false, 915 wrap : false, 916 last : false 917 }; 918 919 $('input[data-zoom-slider-preview]').each((index, input) => { 920 input = $(input);
921 const wrap = input.parent(); 922 wrap.on('mouseenter', () => { 923 this.bindZoomSliderPreview(wrap, input); 924 }); 925 926 wrap.on('mouseleave', () => { 927 this.unbindZoomSliderPreview(); 928 }); 929 }); 930 } 931 932 WPGMZA.MapEditPage.prototype.bindZoomSliderPreview = function(wrap, input){ 933 if(this._zoomPreviewState.type){ 934 /* Unbind existing references */ 935 this.unbindZoomSliderPreview(); 936 } 937 938 this._zoomPreviewState.type = input.attr('id'); 939 this._zoomPreviewState.revert = this.map.getZoom(); 940 this._zoomPreviewState.input = input; 941 this._zoomPreviewState.wrap = wrap; 942 943 const title = input.attr('data-zoom-slider-preview'); 944 945 $("#wpgmza-map-container").append(`<div class='zoom-slider-preview-frame'><span>${title} <span></span></span></div>`); 946 947 this._zoomPreviewState.wrap.on('mousemove', () => { 948 this.onZoomSliderPreviewChange(); 949 }); 950 } 951 952 WPGMZA.MapEditPage.prototype.unbindZoomSliderPreview = function(){ 953 if(this._zoomPreviewState){ 954 if(this._zoomPreviewState.wrap){ 955 this._zoomPreviewState.
955wrap.off('mousemove'); 956 } 957 958 if(this._zoomPreviewState.revert){ 959 $("input[name='map_start_zoom']").val(this._zoomPreviewState.revert); 960 this.map.setZoom(this._zoomPreviewState.revert); 961 } 962 } 963 964 $('.zoom-slider-preview-frame').remove(); 965 966 /* Reset state tracker */ 967 this._zoomPreviewState.type = false; 968 this._zoomPreviewState.revert = false; 969 this._zoomPreviewState.input = false; 970 this._zoomPreviewState.wrap = false; 971 this._zoomPreviewState.last = false; 972 } 973 974 WPGMZA.MapEditPage.prototype.onZoomSliderPreviewChange = function(event){ 975 if(this._zoomPreviewState && this._zoomPreviewState.input){ 976 if(this._zoomPreviewState.input.val()){ 977 const current = parseInt(this._zoomPreviewState.input.val()); 978 if(this._zoomPreviewState.last !== current){ 979 this._zoomPreviewState.last = current; 980 this.map.setZoom(current); 981 982 let delta = current >= this._zoomPreviewState.revert ? (current - this._zoomPreviewState.revert) : -(this._zoomPreviewState.revert - current); 983 $('.zoom-slider-preview-frame span span').text('(' + (delta >= 0 ? `+${delta}` : delta) + ')'); 984 } 985 } 986 } 987 } 988 989 $(document).ready(function(event) { 990 991 WPGMZA.mapEditPage = WPGMZA.MapEditPage.createInstance(); 992 993 }); 994 995});
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.