1/** 2 * Shared jQuery UI datepicker helpers (classic checkout, admin order edit). 3 */ 4(function ($) { 5 'use strict'; 6 7 var DATEPICKER_FORMAT_PRESETS = ['yy-mm-dd', 'mm/dd/yy', 'd MM, y', 'd M, y', 'DD, d MM, yy']; 8 9 function isValidDatepickerOffset(offset) { 10 var value = $.trim(offset || ''); 11 if (!value) { 12 return true; 13 } 14 return /^(?:[+\-]?\d+\s*[dmwy]?)(?:\s+[+\-]?\d+\s*[dmwy]?)*$/i.test(value); 15 } 16 17 function normalizeDatepickerYearRange(range) { 18 var value = $.trim(range || ''); 19 if (!value || value.indexOf(':') === -1) { 20 return value; 21 } 22 var parts = value.split(':'); 23 if (parts.length !== 2) { 24 return value; 25 } 26 var normalizePart = function (part) { 27 part = $.trim(part || ''); 28 if (!part) { 29 return part; 30 } 31 if (/^c[+\-]/i.test(part)) { 32 return part; 33 } 34 if (/^[+\-]/.test(part)) { 35 return part; 36 } 37 if (/^\d{4}$/.test(part)) { 38 return part; 39 } 40 if (/^\d{1,3}$/.test(part)) { 41 return '+' + part; 42 } 43 return part; 44 }; 45 return normalizePart(parts[0]) + ':' + normalizePart(parts[1]); 46 } 47 48 function isValidDatepickerYearRange(range) { 49 var value = normalizeDatepickerYearRange(range); 50 if (!value) { 51 return true; 52 } 53 return /^([+\-]\d+|c[+\-]\d+|\d{4}):([+\-]\d+|c[+\-]\d+|\d{4})$/i.test(value); 54 } 55 56 function tryResolveDatepickerValue(value, dateFormat, minDate) { 57 if (value === 0 || value === '0') { 58 return 0; 59 } 60 if (value === undefined || value === null || value === '') { 61 return null; 62 } 63 if (typeof $.fn.datepicker !== 'function') { 64 return null; 65 } 66 67 var format = dateFormat || 'yy-mm-dd'; 68 var $tmp = $('<input type="text" style="position:absolute;left:-9999px;top:-9999px;" aria-hidden="true">').appendTo('body'); 69 70 try { 71 var opts = { dateFormat: format }; 72 if (minDate !== undefined && minDate !== null && minDate !== '') { 73 opts.minDate = minDate; 74 } 75 $tmp.datepicker(opts); 76 77 var inst = $.datepicker._getInst($tmp[0]); 78 var date = $.datepicker._determineDate(inst, String(value).trim(), new Date()); 79 if (!date) { 80 return null; 81 } 82 return date; 83 } catch (e) { 84 return null; 85 } finally { 86 try { 87 $tmp.datepicker('destroy'); 88 } catch (destroyErr) { 89 // ignore 90 } 91 $tmp.remove(); 92 } 93 } 94 95 function isApplicableDatepickerBound(value, dateFormat, minDate) { 96 if (value === 0 || value === '0') { 97 return true; 98 } 99 if (value === undefined || value === null || $.trim(String(value)) === '') { 100 return false; 101 } 102 return tryResolveDatepickerValue(value, dateFormat, minDate) !== null; 103 } 104 105 function compareDatepickerBounds(left, right) { 106 var leftTime = left === 0 ? new Date().setHours(0, 0, 0, 0) : left.getTime(); 107 var rightTime = right === 0 ? new Date().setHours(0, 0, 0, 0) : right.getTime(); 108 return leftTime - rightTime; 109 } 110 111 function sanitizeDatepickerConfig(config) { 112 config = config || {}; 113 var dateFormat = config.dateFormat || 'yy-mm-dd'; 114 var sanitized = { 115 dateFormat: dateFormat, 116 numberOfMonths: Math.max(1, Math.min(3, parseInt(config.numberOfMonths, 10) || 1)) 117 }; 118 var canTest = typeof $.fn.datepicker === 'function'; 119 120 if (config.yearRange && isValidDatepickerYearRange(config.yearRange)) { 121 var normalizedYearRange = normalizeDatepickerYearRange(config.yearRange); 122 var yearRangeOk = true; 123 124 if (canTest) { 125 var $yearTmp = $('<input type="text" style="position:absolute;left:-9999px;top:-9999px;" aria-hidden="true">').appendTo('body'); 126 try { 127 $yearTmp.datepicker({ changeYear: true, yearRange: normalizedYearRange }); 128 $yearTmp.datepicker('destroy'); 129 } catch (yearErr) { 130 yearRangeOk = false; 131 } 132 $yearTmp.remove(); 133 } 134 135 if (yearRangeOk) { 136 sanitized.yearRange = normalizedYearRange; 137 } 138 } 139 140 if (config.minDate !== undefined && config.minDate !== null && config.minDate !== '') { 141 if (canTest && isApplicableDatepickerBound(config.minDate, dateFormat)) { 142 sanitized.minDate = config.minDate; 143 } else if (!canTest && (config.minDate === 0 || config.minDate === '0' || isValidDatepickerOffset(String(config.minDate)))) { 144 sanitized.minDate = config.minDate; 145 } 146 } 147 148 if (config.maxDate !== undefined && config.maxDate !== null && config.maxDate !== '') { 149 if (canTest && isApplicableDatepickerBound(config.maxDate, dateFormat, sanitized.minDate)) { 150 sanitized.maxDate = config.maxDate; 151 } else if (!canTest && isValidDatepickerOffset(String(config.maxDate))) { 152 sanitized.maxDate = config.maxDate; 153 } 154 } 155 156 if (canTest && sanitized.minDate !== undefined && sanitized.maxDate !== undefined) { 157 var resolvedMin = tryResolveDatepickerValue(sanitized.minDate, dateFormat); 158 var resolvedMax = tryResolveDatepickerValue(sanitized.maxDate, dateFormat, sanitized.minDate); 159 if (resolvedMin !== null && resolvedMax !== null && compareDatepickerBounds(resolvedMin, resolvedMax) > 0) { 160 delete sanitized.maxDate; 161 } 162 } 163 164 if (config.defaultDate !== undefined && config.defaultDate !== null && $.trim(String(config.defaultDate)) !== '') { 165 var defaultDate = $.trim(String(config.defaultDate)); 166 if (canTest && isApplicableDatepickerBound(defaultDate, dateFormat, sanitized.minDate)) { 167 var resolvedDefault = tryResolveDatepickerValue(defaultDate, dateFormat, sanitized.minDate); 168 var includeDefault = true; 169 170 if (resolvedDefault !== null) { 171 if (sanitized.minDate !== undefined) { 172 var resolvedDefaultMin = tryResolveDatepickerValue(sanitized.minDate, dateFormat); 173 if (resolvedDefaultMin !== null && compareDatepickerBounds(resolvedDefault, resolvedDefaultMin) < 0) { 174 includeDefault = false;
175 } 176 } 177 if (includeDefault && sanitized.maxDate !== undefined) { 178 var resolvedDefaultMax = tryResolveDatepickerValue(sanitized.maxDate, dateFormat, sanitized.minDate); 179 if (resolvedDefaultMax !== null && compareDatepickerBounds(resolvedDefault, resolvedDefaultMax) > 0) { 180 includeDefault = false; 181 } 182 } 183 } 184 185 if (includeDefault) { 186 sanitized.defaultDate = defaultDate; 187 } 188 } else if (!canTest && isValidDatepickerOffset(defaultDate)) { 189 sanitized.defaultDate = defaultDate; 190 } 191 } 192 193 if (config.yearRangeMinYear && config.yearRangeMaxYear) { 194 var minYear = parseInt(config.yearRangeMinYear, 10); 195 var maxYear = parseInt(config.yearRangeMaxYear, 10); 196 if (minYear && maxYear && minYear <= maxYear && sanitized.yearRange) { 197 sanitized.yearRangeMinYear = minYear; 198 sanitized.yearRangeMaxYear = maxYear; 199 } 200 } 201 202 if (config.changeYear) { 203 sanitized.changeYear = true; 204 } 205 206 if (config.effectiveMinDate !== undefined && config.effectiveMinDate !== null && config.effectiveMinDate !== '') { 207 sanitized.effectiveMinDate = config.effectiveMinDate; 208 } 209 210 if (config.effectiveMaxDate !== undefined && config.effectiveMaxDate !== null && config.effectiveMaxDate !== '') { 211 sanitized.effectiveMaxDate = config.effectiveMaxDate; 212 } 213 214 if (Array.isArray(config.disabledDays)) { 215 sanitized.disabledDays = config.disabledDays; 216 } 217 if (Array.isArray(config.disabledDates)) { 218 sanitized.disabledDates = config.disabledDates; 219 } 220 221 return sanitized; 222 } 223 224 function resolveDefaultDateOffset(offset, minDate, dateFormat) { 225 if (!offset || typeof offset !== 'string' || !offset.trim()) { 226 return ''; 227 } 228 if (typeof $.fn.datepicker !== 'function') { 229 return ''; 230 } 231 232 var format = dateFormat || 'yy-mm-dd'; 233 var $tmp = $('<input type="text" style="position:absolute;left:-9999px;top:-9999px;" aria-hidden="true">').appendTo('body'); 234 235 try { 236 var opts = { dateFormat: format }; 237 if (minDate !== undefined && minDate !== null && minDate !== '') { 238 opts.minDate = minDate; 239 } 240 $tmp.datepicker(opts); 241 242 var inst = $.datepicker._getInst($tmp[0]); 243 var date = $.datepicker._determineDate(inst, offset.trim(), new Date()); 244 if (!date) { 245 return ''; 246 } 247 return $.datepicker.formatDate(format, date); 248 } catch (e) { 249 return ''; 250 } finally { 251 try { 252 $tmp.datepicker('destroy'); 253 } catch (destroyErr) { 254 // ignore 255 } 256 $tmp.remove(); 257 } 258 } 259 260 function applyDefaultDateToInput($input, config) { 261 if (!$input || !$input.length) { 262 return false; 263 } 264 265 config = config || {}; 266 var currentVal = ($input.val() || '').trim(); 267 if (currentVal) { 268 return false; 269 } 270 271 var defaultDate = config.defaultDate; 272 if (!defaultDate) { 273 return false; 274 } 275 276 var resolved = resolveDefaultDateOffset( 277 defaultDate, 278 config.minDate, 279 config.dateFormat || 'yy-mm-dd' 280 ); 281 if (!resolved) { 282 return false; 283 } 284 285 $input.val(resolved); 286 if ($input.hasClass('hasDatepicker')) { 287 try { 288 $input.datepicker('setDate', resolved); 289 } catch (e) { 290 // Keep typed value when datepicker cannot parse the stored format. 291 } 292 } 293 294 $input.trigger('change').trigger('input'); 295 296 if (typeof window.fmeCcfwRefreshTimepickersForDate === 'function') { 297 var fieldName = $input.attr('name') || $input.attr('id') || ''; 298 window.fmeCcfwRefreshTimepickersForDate(fieldName); 299 } 300 301 return true; 302 } 303 304 window.fmeCcfwDatepickerConfig = { 305 resolveDefaultDateOffset: resolveDefaultDateOffset,
306 applyDefaultDateToInput: applyDefaultDateToInput, 307 sanitizeConfig: sanitizeDatepickerConfig 308 }; 309})(jQuery);
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.