PageSourceSearch

https://mountaincabinsutah.com/wp-content/plugins/homerunner-toolk…/explorer-loading-stability.js?ver=3.309.18

js mountaincabinsutah.com collected 2026-10-10 02:02:24 UTC 3,725 bytes, 121 lines download raw bytes

1/**
2 * Explorer Loading Stability — frontend.
3 *
4 * Kills the layout jump when the explorer swaps property cards for loading
5 * skeletons. Two causes, two fixes:
6 *
7 *   1. The plugin renders at most 8 skeletons regardless of per-page
8 *      (Math.min(perPage, 8) "to prevent the page from becoming too long"),
9 *      so a 12-card grid collapses to 8 placeholders on every refilter.
10 *      Fix: top the skeletons up by cloning until they match the card count
11 *      that was just on screen. The plugin's own success handler consumes
12 *      skeletons FIFO and removes any leftovers, so clones are absorbed by
13 *      its normal flow.
14 *
15 *   2. Skeleton cards are not the same height as real cards, so even a
16 *      matched count shifts the page a little. Fix: pin the grid's
17 *      min-height to its settled (pre-loading) height for the duration of
18 *      the load, released when real cards land.
19 *
20 * The grid is flex-wrap with default align-content, so the min-height pin
21 * alone makes flex distribute the pinned height across the skeleton rows —
22 * on a 100-per-page grid every skeleton stretched ~2.6x (293x305 →
23 * 293x797). The pin therefore comes with align-content: flex-start for
24 * its duration: skeletons keep their natural height and the excess pinned
25 * space stays empty below them.
26 *
27 * The `loading` class toggles synchronously around the card swap, so the
28 * settled height/count are tracked on every load COMPLETION (the mutation
29 * callback runs after the swap — measuring at loading-start would already
30 * see the skeleton state).
31 */
32(function () {
33	'use strict';
34
35	var MAX_SKELETONS = 48; // sanity cap on top-up cloning
36
37	function grids( root ) {
38		return root.querySelectorAll( '.hfse-properties' );
39	}
40
41	function watch( root ) {
42		var settledHeight = 0;
43		var settledCards  = 0;
44
45		function measure() {
46			var grid = grids( root )[ 0 ];
47			if ( ! grid ) {
48				return;
49			}
50			var cards = grid.querySelectorAll( '.property-item:not(.property-loading)' ).length;
51			if ( cards > 0 ) {
52				settledCards  = cards;
53				settledHeight = grid.offsetHeight;
54			}
55		}
56
57		function onLoadingStart() {
58			var grid = grids( root )[ 0 ];
59			if ( ! grid ) {
60				return;
61			}
62
63			if ( settledHeight > 0 ) {
64				grid.style.minHeight = settledHeight + 'px';
65				grid.style.alignContent = 'flex-start';
66			}
67
68			var skeletons = grid.querySelectorAll( '.property-loading' );
69			var want      = Math.min( settledCards, MAX_SKELETONS );
70			var template  = skeletons[ skeletons.length - 1 ];
71			if ( ! template || skeletons.length >= want ) {
72				return;
73			}
74			for ( var i = skeletons.length; i < want; i++ ) {
75				grid.appendChild( template.cloneNode( true ) );
76			}
77		}
78
79		function onLoadingEnd() {
80			var grid = grids( root )[ 0 ];
81			if ( grid ) {
82				grid.style.minHeight = '';
83				grid.style.alignContent = '';
84			}
85			measure();
86		}
87
88		var wasLoading = root.classList.contains( 'loading' );
89
90		new MutationObserver( function () {
91			var isLoading = root.classList.contains( 'loading' );
92			if ( isLoading === wasLoading ) {
93				return;
94			}
95			wasLoading = isLoading;
96			if ( isLoading ) {
97				onLoadingStart();
98			} else {
99				onLoadingEnd();
100			}
101		} ).observe( root, { attributes: true, attributeFilter: [ 'class' ] } );
102
103		// Settled baseline for the first refilter (initial load may still be
104		// in flight; measure() ignores empty grids and the loading-end hook
105		// re-measures after every completed load).
106		measure();
107	}
108
109	function start() {
110		if ( ! window.MutationObserver ) {
111			return;
112		}
113		document.querySelectorAll( '.hfse' ).forEach( watch );
114	}
115
116	if ( 'loading' === document.readyState ) {
117		document.addEventListener( 'DOMContentLoaded', start );
118	} else {
119		start();
120	}
121})();

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.