1/*********************************************** 2* Shared server clock. Replaces the per-page copies of the old Dynamic Drive 3* "Local Time script" that lived inline in Defaults/*.aspx and Headers/*.aspx. 4* 5* Config-node contract (rendered by SEO/LocalTime.ascx). The clock writes into 6* an element that already exists in the page, so brand-specific container markup 7* (style/class/td/a/...) stays exactly as it was: 8* 9* <span id="timecontainer" style="font-family: euphemia"></span> 10* <span data-localtime-for="timecontainer" 11* data-servertime="2026-07-31 14:05:33" 12* data-format="{d}/{MMM}/{yyyy} {HH}:{mm}:{ss} GMT+8" 13* data-weekdays='["Sunday","Monday",...]' hidden></span> 14* 15* Everything outside {...} in data-format is literal text, so each brand keeps 16* its own layout in the markup instead of forking the script. 17***********************************************/ 18(function () { 19 var defaultPagePath = /\/defaults\/default\d+\.aspx$/i; 20 if (window.top === window.self && defaultPagePath.test(location.pathname)) { 21 location.replace(location.pathname.replace(defaultPagePath, '/') + location.search + location.hash); 22 } 23})(); 24 25(function () { 26 'use strict'; 27 28 var MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; 29 var MONTHS_FULL = ['January', 'February', 'March', 'April', 'May', 'June', 30 'July', 'August', 'September', 'October', 'November', 'December']; 31 // Fallback only â the control always supplies data-weekdays from Resources.Resource.*. 32 // Mirrors the neutral Resource.resx values (short form), not the English long names, 33 // so a missing attribute degrades to what EN actually renders. 34 var WEEKDAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; 35 var WEEKDAYS_SHORT = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat']; 36 37 function pad(n) { return n < 10 ? '0' + n : String(n); } 38 function to12(h) { var r = h % 12; return r === 0 ? 12 : r; } 39 // The legacy pages did a bare `if (hour > 12) hour -= 12`, which leaves midnight 40 // as 0 rather than 12. Kept as its own token so migrated brands render exactly as 41 // before; use {h}/{hh} for a correct 12-hour clock. 42 function legacy12(h) { return h > 12 ? h - 12 : h; } 43 44 function tokenValue(token, d, weekdays, months) { 45 switch (token) { 46 case 'ddd': return weekdays[d.getDay()] || ''; // localised, from Resources 47 case 'eee': return WEEKDAYS_SHORT[d.getDay()]; // fixed English Sun..Sat 48 case 'dd': return pad(d.getDate()); 49 case 'd': return String(d.getDate()); 50 case 'MMMM': return MONTHS_FULL[d.getMonth()]; 51 case 'MMM': return months[d.getMonth()] || ''; 52 case 'MM': return pad(d.getMonth() + 1); 53 case 'M': return String(d.getMonth() + 1); 54 case 'yyyy': return String(d.getFullYear()); 55 case 'yy': return pad(d.getFullYear() % 100); 56 case 'HH': return pad(d.getHours()); 57 case 'H': return String(d.getHours()); 58 case 'hh12': return pad(legacy12(d.getHours())); 59 case 'h12': return String(legacy12(d.getHours())); 60 case 'hh': return pad(to12(d.getHours())); 61 case 'h': return String(to12(d.getHours())); 62 case 'mm': return pad(d.getMinutes()); 63 case 'm': return String(d.getMinutes()); 64 case 'ss': return pad(d.getSeconds()); 65 case 's': return String(d.getSeconds()); 66 case 'A': return d.getHours() >= 12 ? 'PM' : 'AM'; 67 case 'a': return d.getHours() >= 12 ? 'pm' : 'am'; 68 default: return '{' + token + '}'; // unknown token: show it rather than blank the clock 69 } 70 } 71 72 function format(d, fmt, weekdays, months) { 73 return fmt.replace(/\{(\w+)\}/g, function (whole, token) { 74 return tokenValue(token, d, weekdays, months); 75 }); 76 } 77 78 // "yyyy-MM-dd HH:mm:ss" -> Date built from the numbers. Explicit components 79 // because new Date(<string>) is implementation-defined: the old code fed it 80 // "MM/dd/yyyy HH:mm:ss", which only parsed reliably in Chrome. 81 function parseServerTime(s) { 82 var m = /^(\d{4})-(\d{2})-(\d{2})[ T](\d{2}):(\d{2}):(\d{2})$/.exec(s || ''); 83 if (!m) return new Date(); 84 return new Date(+m[1], +m[2] - 1, +m[3], +m[4], +m[5], +m[6]); 85 } 86 87 function parseList(raw, fallback) { 88 if (!raw) return fallback; 89 try { 90 var list = JSON.parse(raw); 91 return (list && list.length) ? list : fallback; 92 } catch (e) { 93 return fallback; 94 } 95 } 96 97 function start(cfg) { 98 var target = document.getElementById(cfg.getAttribute('data-localtime-for')); 99 if (!target || cfg.getAttribute('data-localtime-started')) return; 100 cfg.setAttribute('data-localtime-started', '1'); 101 102 var fmt = cfg.getAttribute('data-format') || '{MMM}/{d}/{yyyy} {HH}:{mm}:{ss}'; 103 var weekdays = parseList(cfg.getAttribute('data-weekdays'), WEEKDAYS); 104 var months = parseList(cfg.getAttribute('data-months'), MONTHS); 105 106 // Hold the server/client gap instead of incrementing a counter every tick, 107 // so a throttled background tab resyncs instead of falling behind. 108 var skew = parseServerTime(cfg.getAttribute('data-servertime')).getTime() - Date.now(); 109 110 function tick() { 111 // textContent, not innerHTML: the clock only ever emits text, and this 112 // keeps the widget off the DOM-sink list entirely. 113 target.textContent = format(new Date(Date.now() + skew), fmt, weekdays, months); 114 } 115 116 tick(); 117 // One timer per clock. The original started two independent setTimeout 118 // chains per instance, which drifted apart and could never be stopped. 119 setInterval(tick, 1000); 120 } 121
122 function init() { 123 var nodes = document.querySelectorAll('[data-localtime-for]'); 124 for (var i = 0; i < nodes.length; i++) start(nodes[i]); 125 } 126 127 if (document.readyState === 'loading') 128 document.addEventListener('DOMContentLoaded', init); 129 else 130 init(); 131})();
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.