1/* âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 2 LocalBusiness NAP Block (W-001) â progressive-enhancement behavior. 3 4 The card, the hours <dl>, and the canonical JSON-LD are ALL server-rendered 5 and fully functional without this file (progressive enhancement). nap.js adds 6 exactly two additive layers, both guarded so a load failure degrades to the 7 static card: 8 9 1. OPEN-NOW PILL â a guarded CONSUMER of the shared hzo.hours model (W-002). 10 It NEVER re-parses hours (Part 0 rule 3): it reads hzo.hours.state()/today() 11 and re-syncs on the reserved `hzo:hourschange` event, toggling the 12 .hzo-nap__status pill (words carry meaning, not color) and marking today's 13 <dl> row [aria-current]. Absent hours model â no pill; the static <dl> 14 still renders. NAP produces NO hzo:* event of its own. 15 16 2. MEASUREMENT ADAPTER â the fleet's highest-value untracked action. Mirrors a 17 `tel:` tap inside any [data-hzo-nap] to dataLayer as `phone_call`. Hooks the 18 DOM anchor directly (NAP emits no internal event to mirror). 19 20 Reveal is NOT handled here â the shared .hzo-reveal hook (main.js) owns it. This 21 file is idempotent (guarded by data-hzo-nap-ready) and reduced-motion safe (it 22 only toggles classes/text; the pill's transition is killed in CSS under reduce). 23 âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ */ 24(function () { 25 'use strict'; 26 27 window.hzo = window.hzo || {}; 28 29 function __(s) { 30 return (window.wp && wp.i18n && wp.i18n.__) ? wp.i18n.__(s, 'hozio-studio') : s; 31 } 32 33 // ââ Open-now pill ââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ 34 // Reflect the current hours state onto every NAP card's pill + today's row. 35 function reflect(root) { 36 if (!(window.hzo && window.hzo.hours)) { return; } // model absent â leave static <dl> 37 var pill = root.querySelector('[data-hzo-nap-status]'); 38 var state, today; 39 try { 40 state = window.hzo.hours.state(); 41 today = window.hzo.hours.today(); 42 } catch (e) { return; } 43 44 if (pill) { 45 var open = state !== 'closed'; 46 pill.classList.toggle('is-open', open); 47 pill.classList.toggle('is-closed', !open); 48 pill.textContent = open ? __('Open now') : __('Closed'); 49 pill.hidden = false; 50 } 51 52 // Mark today's <dl> row (match the <dt> whose day matches today.day). 53 if (today && today.day) { 54 var wanted = String(today.day).slice(0, 3).toLowerCase(); 55 var dts = root.querySelectorAll('.hzo-hours dt'); 56 for (var i = 0; i < dts.length; i++) { 57 var isToday = dts[i].textContent.slice(0, 3).toLowerCase() === wanted; 58 if (isToday) { dts[i].setAttribute('aria-current', 'true'); } 59 else { dts[i].removeAttribute('aria-current'); } 60 } 61 } 62 } 63 64 function reflectAll() { 65 var roots = document.querySelectorAll('[data-hzo-nap]'); 66 for (var i = 0; i < roots.length; i++) { reflect(roots[i]); } 67 } 68 69 // ââ Measurement: tel: tap â dataLayer phone_call âââââââââââââââââââââââââââ 70 // Delegated + idempotent (bound once). Desktop tel: no-ops silently, so the 71 // number is ALSO visible selectable text in the card (server-rendered) â this 72 // only measures the intent, it is not the fallback. 73 function bindMeasurement() { 74 if (window.hzo.__napMeasureBound) { return; } 75 window.hzo.__napMeasureBound = true; 76 document.addEventListener('click', function (e) { 77 var a = e.target && e.target.closest ? e.target.closest('[data-hzo-nap] a[href^="tel:"]') : null; 78 if (!a) { return; } 79 window.dataLayer = window.dataLayer || []; 80 window.dataLayer.push({ 81 event: 'phone_call', 82 phone_number: a.getAttribute('href').replace(/^tel:/, ''), 83 source: 'nap' 84 }); 85 }, true); 86 } 87 88 // ââ Init (idempotent) ââââââââââââââââââââââââââââââââââââââââââââââââââââââ
89 function init() { 90 var roots = document.querySelectorAll('[data-hzo-nap]:not([data-hzo-nap-ready])'); 91 if (roots.length) { 92 for (var i = 0; i < roots.length; i++) { roots[i].setAttribute('data-hzo-nap-ready', ''); } 93 } 94 bindMeasurement(); 95 reflectAll(); 96 } 97 98 // Re-sync the pill whenever the shared model flips open/after-hours state. 99 // Guarded + bound once; NAP is a consumer, never a producer, of this event. 100 if (!window.hzo.__napHoursBound) { 101 window.hzo.__napHoursBound = true; 102 document.addEventListener('hzo:hourschange', reflectAll); 103 } 104 105 // Expose for AJAX-injected instances (mirrors the widget convention). 106 window.hzo.nap = { init: init, reflect: reflect }; 107 108 if (document.readyState === 'loading') { 109 document.addEventListener('DOMContentLoaded', init); 110 } else { 111 init(); 112 } 113})();
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.