PageSourceSearch

https://effortlessstay.com/wp-content/plugins/homerunner-toolkit/assets/js/anb-frontend.js?ver=3.286.1

js effortlessstay.com collected 2026-09-29 00:57:48 UTC 4,898 bytes, 140 lines download raw bytes

1/**
2 * HomeRunner Toolkit — Advance Notice Blocking (frontend)
3 *
4 * Patches the booking widget calendar utility and the explorer range
5 * calendar plugin so dates inside the advance-notice window are treated
6 * as unavailable with a clear tooltip.
7 *
8 * Config (window.hrtkAdvanceNotice):
9 *   - hours   number  Hours of advance notice required.
10 *   - days    number  hours / 24, rounded up.
11 *   - tooltip string  Pre-formatted tooltip text (already has %d filled in).
12 */
13/* global jQuery */
14(function () {
15	'use strict';
16
17	var cfg = window.hrtkAdvanceNotice || { hours: 0, days: 0, tooltip: '' };
18	if (!cfg.hours || cfg.hours <= 0) return;
19
20	var noticeMs = cfg.hours * 60 * 60 * 1000;
21
22	// Server-computed earliest bookable check-in date (Y-m-d, site timezone).
23	// Comparing calendar dates against this fixed boundary is deterministic for
24	// every visitor; the old browser-clock math was off by up to a day for
25	// guests in a different timezone than the property.
26	var minCheckinMs = null;
27	if (cfg.minCheckin) {
28		// Parse as a date-only value at UTC midnight, then compare against the
29		// candidate date also normalised to UTC midnight, so neither side
30		// depends on the browser timezone.
31		var parts = String(cfg.minCheckin).split('-');
32		if (parts.length === 3) {
33			minCheckinMs = Date.UTC(parseInt(parts[0], 10), parseInt(parts[1], 10) - 1, parseInt(parts[2], 10));
34		}
35	}
36
37	// Normalise a date (Date or string) to UTC midnight ms for day-granular
38	// comparison, independent of the browser timezone.
39	function dayStartUtcMs(date) {
40		if (!date) return NaN;
41		var d = (date instanceof Date) ? date : new Date(date);
42		if (isNaN(d.getTime())) return NaN;
43		// Use the date's UTC components: calendar dates from the host arrive as
44		// "YYYY-MM-DD" which JS parses as UTC midnight already.
45		return Date.UTC(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate());
46	}
47
48	function isInsideWindow(date) {
49		if (!date) return false;
50
51		if (minCheckinMs !== null) {
52			var dayMs = dayStartUtcMs(date);
53			if (isNaN(dayMs)) return false;
54			return dayMs < minCheckinMs;
55		}
56
57		// Fallback (no server boundary available): legacy browser-clock math.
58		var d = (date instanceof Date) ? date : new Date(date);
59		if (isNaN(d.getTime())) return false;
60		var diff = d.getTime() - Date.now();
61		return diff < noticeMs;
62	}
63
64	// Layer 1 — booking widget calendar utility.
65	function patchCalendarUtils() {
66		// The host declares `class HomeLocalCalendarUtils {…}` at top-level in
67		// calendar-utils.js with no window.X assignment — so it's a lexical
68		// global binding, NOT a property of window. Bare-name access works
69		// across classic scripts; `window.HomeLocalCalendarUtils` is undefined.
70		if (typeof HomeLocalCalendarUtils !== 'function' || !HomeLocalCalendarUtils.prototype) {
71			return false;
72		}
73		if (HomeLocalCalendarUtils.prototype.__hrtkAnbPatched) return true;
74
75		var orig = HomeLocalCalendarUtils.prototype._calculateCanCheckin;
76		HomeLocalCalendarUtils.prototype._calculateCanCheckin = function (date) {
77			if (isInsideWindow(date)) {
78				return { status: false, message: cfg.tooltip };
79			}
80			if (typeof orig === 'function') {
81				return orig.apply(this, arguments);
82			}
83			return { status: true };
84		};
85		HomeLocalCalendarUtils.prototype.__hrtkAnbPatched = true;
86		return true;
87	}
88
89	// Layer 2 — explorer range calendar jQuery plugin.
90	function patchRangeCalendar() {
91		if (!window.jQuery || !jQuery.fn || !jQuery.fn.homelocalRangeCalendar) return false;
92		if (jQuery.fn.homelocalRangeCalendar.__hrtkAnbPatched) return true;
93
94		var origPlugin = jQuery.fn.homelocalRangeCalendar;
95		jQuery.fn.homelocalRangeCalendar = function () {
96			var ret = origPlugin.apply(this, arguments);
97			this.each(function () {
98				var inst = jQuery(this).data('homelocalRangeCalendar');
99				if (!inst || inst.__hrtkAnbPatched) return;
100				inst.__hrtkAnbPatched = true;
101
102				if (typeof inst.isUnavailable === 'function') {
103					var origUnavail = inst.isUnavailable.bind(inst);
104					inst.isUnavailable = function (date) {
105						return isInsideWindow(date) || origUnavail(date);
106					};
107				}
108				if (typeof inst.canCheckin === 'function') {
109					var origCanCheckin = inst.canCheckin.bind(inst);
110					inst.canCheckin = function (date) {
111						if (isInsideWindow(date)) {
112							return { status: false, message: cfg.tooltip };
113						}
114						return origCanCheckin(date);
115					};
116				}
117			});
118			return ret;
119		};
120		jQuery.fn.homelocalRangeCalendar.__hrtkAnbPatched = true;
121		return true;
122	}
123
124	// Try immediately, then retry briefly while the host scripts finish loading.
125	function attemptPatch() {
126		var calendarOk = patchCalendarUtils();
127		var rangeOk    = patchRangeCalendar();
128		return calendarOk && rangeOk;
129	}
130
131	if (attemptPatch()) return;
132
133	var attempts = 0;
134	var iv = setInterval(function () {
135		attempts++;
136		if (attemptPatch() || attempts > 60) {
137			clearInterval(iv);
138		}
139	}, 150);
140})();

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.