Skip to content

J & J Reliable Door

Categories

DOORS

Scroll To Top (function () { var SCOPE = '.upc-events'; var ITEM = '.mn-scroll-item'; var DATE = '.mn-scroll-date'; var MONTHS = { jan: 0, feb: 1, mar: 2, apr: 3, may: 4, jun: 5, jul: 6, aug: 7, sep: 8, oct: 9, nov: 10, dec: 11 }; var LAST = Number.MAX_SAFE_INTEGER; // unparseable dates sink to the bottom var DAY_MS = 864e5; var GRACE_DAYS = 1; // a date this recently past still counts as "current year" var HREF_DATE = /-(\d{2})-(\d{2})-(\d{4})-\d+(?:[\/?#]|$)/; // ...-09-16-2026-5284 var TEXT_DATE = /([A-Za-z]{3})[a-z]*\.?\s+(\d{1,2})(?:[^\d]+(\d{4}))?/; var wired = new WeakSet(); /* --- date resolution ------------------------------------------------- */ // "MMM d" carries no year, so roll forward when the day has already passed. function inferYear(month, day) { var now = new Date(); var d = new Date(now.getFullYear(), month, day); if (d.getTime() < now.getTime() - GRACE_DAYS * DAY_MS) { d.setFullYear(d.getFullYear() + 1); } return d.getTime(); } function getTime(item) { // Detail URLs usually embed the real MM-DD-YYYY — trust that first. var link = item.querySelector('a[href]'); var href = link && link.getAttribute('href').match(HREF_DATE); if (href) return new Date(+href[3], +href[1] - 1, +href[2]).getTime(); var el = item.querySelector(DATE); var text = (el ? el.textContent : '').match(TEXT_DATE); if (!text) return LAST; var month = MONTHS[text[1].toLowerCase()]; if (month === undefined) return LAST; return text[3] ? new Date(+text[3], month, +text[2]).getTime() : inferYear(month, +text[2]); } /* --- sorting --------------------------------------------------------- */ function sort(scope) { var groups = new Map(); scope.querySelectorAll(ITEM).forEach(function (item) { var siblings = groups.get(item.parentNode) || []; siblings.push(item); groups.set(item.parentNode, siblings); }); groups.forEach(function (items, parent) { var sorted = items .map(function (el, i) { return { el: el, time: getTime(el), i: i }; }) .sort(function (a, b) { return a.time - b.time || a.i - b.i; }); // Already chronological — leave the DOM alone. if (sorted.every(function (o, i) { return o.i === i; })) return; var frag = document.createDocumentFragment(); sorted.forEach(function (o) { frag.appendChild(o.el); }); parent.appendChild(frag); }); } /* --- init ------------------------------------------------------------ */ function watch(scope) { if (wired.has(scope)) return; wired.add(scope); var opts = { childList: true, subtree: true }; var queued = false; var observer = new MutationObserver(function () { if (queued) return; queued = true; requestAnimationFrame(function () { queued = false; observer.disconnect(); // don't react to our own re-ordering sort(scope); observer.observe(scope, opts); }); }); sort(scope); // in case the widget already rendered observer.observe(scope, opts); } function init() { document.querySelectorAll(SCOPE).forEach(watch); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();