1/** 2 * Map Hover Pan Lock â frontend patcher. 3 * 4 * Hovering a property card calls the explorer's focusMarker(), which 5 * highlights the pin AND pans the map whenever that pin sits outside the 6 * central "safe" bounds of the current view. With search-as-I-move enabled 7 * that pan re-runs the search, so merely grazing the card list reshuffles 8 * the very results the visitor was reading. This module keeps the pin 9 * highlight but suppresses the pan. 10 * 11 * How: a capture-phase mouseover listener raises a flag for exactly the 12 * synchronous window in which the plugin's delegated hover handler (and 13 * therefore its focus() â panTo() call) runs; wrapped panTo prototypes on 14 * Leaflet and Google Maps become no-ops for the explorer map while the flag 15 * is up. Every other pan â pin click, prev/next controls, fit bounds, 16 * search-as-move â reaches the native method untouched. 17 * 18 * Why prototype wraps and not a constructor wrap: the plugin builds the map 19 * inside a closure before this (deferred) script runs, so only methods 20 * called later on the live instance can be intercepted (same approach as 21 * mobile-map-gestures.js). 22 * 23 * Desktop-scoped by gating on (hover: hover): touch devices never truly 24 * hover cards, and their emulated hover events are left alone. 25 */ 26(function () { 27 'use strict'; 28 29 if ( ! window.matchMedia || ! window.matchMedia( '(hover: hover)' ).matches ) { 30 return; 31 } 32 33 var MAX_ATTEMPTS = 200; // 20s at 100ms â covers slow map library loads. 34 var POLL_MS = 100; 35 var CARD = '.hfse-property-container'; 36 37 var hoverActive = false; 38 var clearTimer = 0; 39 40 document.addEventListener( 41 'mouseover', 42 function ( e ) { 43 var t = e.target; 44 if ( ! t || ! t.closest || ! t.closest( CARD ) ) { 45 return; 46 } 47 // The plugin's delegated handler runs during this same event's 48 // bubble phase, synchronously â a 0ms timeout outlives it. 49 hoverActive = true; 50 clearTimeout( clearTimer ); 51 clearTimer = setTimeout( function () { 52 hoverActive = false; 53 }, 0 ); 54 }, 55 true 56 ); 57 58 /* ------------------------------------------------------------------ */ 59 /* Leaflet */ 60 /* ------------------------------------------------------------------ */ 61 62 function isLeafletExplorerMap( map ) { 63 try { 64 var div = map.getContainer && map.getContainer(); 65 return !! ( div && 'map' === div.id && div.closest && div.closest( '.hfse' ) ); 66 } catch ( err ) { 67 return false; 68 } 69 } 70 71 function hookLeaflet( L ) { 72 if ( L.Map.prototype.__hrtkHoverPanLocked ) { 73 return; 74 } 75 L.Map.prototype.__hrtkHoverPanLocked = true; 76 77 var nativePanTo = L.Map.prototype.panTo; 78 L.Map.prototype.panTo = function () { 79 if ( hoverActive && isLeafletExplorerMap( this ) ) { 80 return this; 81 } 82 return nativePanTo.apply( this, arguments ); 83 }; 84 } 85 86 /* ------------------------------------------------------------------ */ 87 /* Google Maps */ 88 /* ------------------------------------------------------------------ */ 89 90 function hookGoogle( maps ) { 91 if ( maps.Map.prototype.__hrtkHoverPanLocked ) { 92 return; 93 } 94 maps.Map.prototype.__hrtkHoverPanLocked = true; 95 96 var nativeGetDiv = maps.Map.prototype.getDiv; 97 var nativePanTo = maps.Map.prototype.panTo; 98 99 maps.Map.prototype.panTo = function () { 100 if ( hoverActive ) { 101 try { 102 var div = nativeGetDiv.call( this ); 103 if ( div && 'map' === div.id && div.closest && div.closest( '.hfse' ) ) { 104 return; 105 } 106 } catch ( err ) { 107 // Fall through to the native pan on any doubt. 108 } 109 } 110 return nativePanTo.apply( this, arguments ); 111 }; 112 } 113 114 var attempts = 0; 115 var leafletDone = false; 116 var googleDone = false; 117 var tick = setInterval( function () { 118 attempts++; 119 120 if ( ! leafletDone && window.L && window.L.Map && window.L.Map.prototype ) { 121 leafletDone = true; 122 try { 123 hookLeaflet( window.L ); 124 } catch ( err ) { 125 // Leave native behaviour intact on any error. 126 } 127 } 128 129 var maps = window.google && window.google.maps; 130 if ( ! googleDone && maps && maps.Map && maps.Map.prototype ) { 131 googleDone = true; 132 try { 133 hookGoogle( maps ); 134 } catch ( err ) { 135 // Leave native behaviour intact on any error. 136 } 137 } 138 139 if ( ( leafletDone && googleDone ) || attempts >= MAX_ATTEMPTS ) { 140 clearInterval( tick ); 141 } 142 }, POLL_MS ); 143})();
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.