PageSourceSearch

https://mountaincabinsutah.com/wp-content/plugins/homerunner-toolk…/js/map-hover-pan-lock.js?ver=3.309.18

js mountaincabinsutah.com collected 2026-10-10 02:02:22 UTC 4,406 bytes, 143 lines download raw bytes

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.