1Object.size = function(obj) { 2 var size = 0, 3 key; 4 for (key in obj) { 5 if (obj.hasOwnProperty(key)) size++; 6 } 7 return size; 8 }; 9 10 /** 11 * Default selectors and template if they are not provided. 12 **/ 13 const _defaultHoursConfig = { 14 selectors:{ 15 container: '.footer-column--hours', 16 title:'.footer-column__header', 17 hoursData: '.footer-column__list', 18 day:'.day', 19 time:'.time' 20 }, 21 template: '<li class="footer-column--hours">'+ 22 '<h4 class="footer-column__header"></h4>'+ 23 '<dl class="footer-column__list">'+ 24 '<dt class="day"></dt>'+ 25 '<dd class="time"></dd>'+ 26 '</dl>'+ 27 '</li>' 28 } 29 30 /** 31 * Format provided time for display on front end of website 32 * Formatting includes converting from military time, adding AM/PM and dropping seconds 33 * @param {string} time A time that will be displayed on the front end 34 */ 35 const parseMil = (time) => { 36 try { 37 const timeArr = time.split(':'); 38 const hours = Number(timeArr[0]); 39 const minutes = Number(timeArr[1]); 40 41 let timeValue; 42 43 if (hours > 0 && hours <=12){ 44 timeValue = "" + hours; 45 } else if (hours > 12){ 46 timeValue = "" + (hours - 12); 47 } else if (hours == 0){ 48 timeValue = "12"; 49 } 50 51 timeValue += (minutes < 10) ? ":0" + minutes : ":" + minutes; 52 timeValue += (hours >= 12) ? " PM" : " AM"; 53 54 return timeValue; 55 } catch (error) { 56 console.error('Hours Editor Error:',error); 57 } 58 } 59 60 /** 61 * Creates and returns an array of openingHoursSpecification objects for the provided hours group 62 * @param {string} group The group to create the schema json ld for 63 */ 64 const renderHoursSchema = (group) => { 65 try { 66 const days = oOperatingHours[group].days; 67 68 let openingHoursSpecification=[] 69 70 // loop through days in hour editor json 71 for (const day of Object.keys(days)) { 72 if (days[day].status === "inactive") { 73 if (days[day].alternate) { 74 openingHoursSpecification.push({"@type":"OpeningHoursSpecification","closes":"00:00:00","dayOfWeek":days[day].name,"opens":"00:00:00","description":days[day].alternate}); 75 } else { 76 openingHoursSpecification.push({"@type":"OpeningHoursSpecification","closes":"00:00:00","dayOfWeek":days[day].name,"opens":"00:00:00"}); 77 } 78 } else { 79 if (days[day].alternate) { 80 openingHoursSpecification.push({"@type":"OpeningHoursSpecification","closes":days[day].closed,"dayOfWeek":days[day].name,"opens":days[day].open,"description":days[day].alternate}); 81 } else { 82 openingHoursSpecification.push({"@type":"OpeningHoursSpecification","closes":days[day].closed,"dayOfWeek":days[day].name,"opens":days[day].open}); 83 } 84 } 85 } 86 87 return openingHoursSpecification; 88 } catch (error) { 89 console.error('Hours Editor Error:',error); 90 } 91 } 92 93 /** 94 * Reorder the week starting at a specified day or Monday if no day provided 95 * @param {object} groupObj hours group days object 96 * @param {int} weekStart day of the week (0=Sunday and 6=Saturday) 97 */ 98 const _reOrderWeek = (groupObj,weekStart=1) => { 99 try { 100 // default week cycle, starting on sunday 101 let stdWeekCycle = ["sunday","monday","tuesday","wednesday","thursday","friday","saturday"]; 102 let weekCycle = []; 103 104 // create weekCycle based on days in hours group days object 105 for (let x=0;x<stdWeekCycle.length;x++) { 106 if (groupObj[stdWeekCycle[x]]) { 107 weekCycle.push(stdWeekCycle[x]); 108 } 109 } 110 111 // adjust first day of weekCycle array (0=sunday - 6=saturday) 112 for (let i=0; i<weekStart; i++) { 113 weekCycle.push(weekCycle.shift()); 114 } 115 116 return weekCycle; 117 } catch (error) { 118 console.error('Hours Editor Error:',error); 119 } 120 } 121 122 /** 123 * Abbreviates day name to three characters 124 * @param {object} days json of hours group days 125 */ 126 const _abbreviateDays = (days) => { 127 try { 128 for (const day in days) { 129 days[day].name=days[day].name.substring(0,3); 130 } 131 132 return days; 133 } catch (error) { 134 console.error('Hours Editor Error:',error); 135 } 136 } 137 138 /** 139 * Convert time from milatary to standard and abbreviate hours if desired 140 * @param {object} days json object of hours group days 141 * @param {bool} hoursAbbr abbreviate hours to hour position 142 */ 143 const _formatHours = (days,hoursAbbr) => { 144 try { 145 for (const day in days) { 146 if (days[day].open!=='closed' && hoursAbbr===true) { 147 days[day].open=parseMil(days[day].open).replace(':00','') 148 days[day].closed=parseMil(days[day].closed).replace(':00','') 149 } else if (days[day].open!=='closed') { 150 days[day].open=parseMil(days[day].open); 151 days[day].closed=parseMil(days[day].closed); 152 } 153 } 154 155 return days; 156 } catch (error) { 157 console.error('Hours Editor Error:',error); 158 } 159 } 160 161 /** 162 * Combine consecutive days that have the same opening and closing time 163 * @param {object} days json of hours group days 164 * @param {weekCycle} arrray array of days with first index the requested start of week day 165 */ 166 const _combineDays = (days,hoursGroup,weekCycle) => { 167 try { 168 const daysTemp={} 169 let current={}; 170 let previous={}; 171 const matches=[]; 172 let day={} 173 174 for (var i=0;
174i<=Object.size(days);i++) { 175 day=days[weekCycle[i]]; 176 177 if (day===undefined) { 178 current={} 179 } else { 180 current=day; 181 } 182 183 if (previous['alternate']===undefined && Object.keys(previous).length) { 184 previous['alternate']=''; 185 } 186 187 if (current['alternate']===undefined && Object.keys(current).length) { 188 current['alternate']=''; 189 } 190 191 if ((current['open']===previous['open'] && current['closed']===previous['closed']) && (current['alternate']===previous['alternate'])) { 192 matches.push(current); 193 } else { 194 if (matches.length>1) { 195 daysTemp[matches[0]['name']+' - '+matches[matches.length-1]['name']]={ 196 name:matches[0]['name']+' - '+matches[matches.length-1]['name'], 197 status:matches[0]['status'], 198 open:matches[0]['open'], 199 closed:matches[0]['closed'], 200 alternate:matches[0]['alternate'] 201 } 202 } else if (matches.length===1) { 203 daysTemp[matches[0]['name']]={ 204 name:matches[0]['name'], 205 status:matches[0]['status'], 206 open:matches[0]['open'], 207 closed:matches[0]['closed'], 208 alternate:matches[0]['alternate'] 209 } 210 } 211 212 // reset matches to empty array 213 while(matches.length > 0) { 214 matches.pop(); 215 } 216 217 matches.push(current); 218 } 219 previous=current; 220 } 221 222 return daysTemp; 223 224 } catch (error) { 225 console.error('Hours Editor Error:',error); 226 } 227 } 228 229 /** 230 * Insert created hours HTML into provided css selector for provided hours group 231 * @param {object} hoursConfig Object containing all settings for rendering the hours 232 * @param {string} target css selector for element to insert newly rendered hours html 233 * @param {string} group hours group to use for rendering 234 * @param {int} weekStart day to start the week on (0 is sunday and 6 is saturday) 235 * @param {bool} daysAbbr abbreviate hours to three characters 236 * @param {bool} hoursAbbr drop minutes placeholder 237 * @param {bool} combineDays combine consecutive days with the same opening and closing time 238 * @param {object} selectors css selectors used in the html template for rendering 239 * @param {string} container css selector for container 240 * @param {string} title css selector for title of hours group 241 * @param {string} hoursData css selector for the container of the hours data 242 * @param {string} day css selector for the tag used for the day 243 * @param {string} time css selector for the tag used for the time 244 * @param {string} template empty html template to use for rendering 245 */ 246 const renderHoursContent = (hoursConfig) => { 247 try { 248 // For readability 249 const oOperatingHoursTemp=JSON.parse(JSON.stringify(oOperatingHours)); // make a copy of oOperatingHours. 250 const target=hoursConfig.target; 251 const hoursGroup=hoursConfig.group; 252 const daysAbbr=hoursConfig.daysAbbr; 253 const hoursAbbr=hoursConfig.hoursAbbr; 254 const weekStart=hoursConfig.weekStart; 255 const combineDays = (hoursConfig.combineHours===undefined) ? hoursConfig.combineDays : hoursConfig.combineHours; 256 // const alternateText=hoursConfig.alternateText; 257 258 // use default if selectors and template null 259 const selectors=hoursConfig.selectors ? hoursConfig.selectors:_defaultHoursConfig.selectors; 260 let $template=hoursConfig.template ? $('<div></div>').html($(hoursConfig.template)):$('<div></div>').html($(_defaultHoursConfig.template)); // wrapping template in div so it is easier to insert with jquery 261 262 // determine where the new hours data will be inserted 263 if (selectors.hoursData) { 264 $hoursTarget=$template.find(selectors.hoursData); 265 } else if (selectors.container) { 266 $hoursTarget=$template.find(selectors.container); 267 } else { 268 $hoursTarget=$template 269 } 270 271 if (daysAbbr) { 272 oOperatingHoursTemp[hoursGroup]['days']=_abbreviateDays(oOperatingHoursTemp[hoursGroup]['days']); 273 } 274 275 oOperatingHoursTemp[hoursGroup]['days']=_formatHours(oOperatingHoursTemp[hoursGroup]['days'],hoursAbbr); 276 277 let weekCycle = _reOrderWeek(oOperatingHours[hoursGroup]['days'],weekStart); 278 279 if (combineDays) { 280 oOperatingHoursTemp[hoursGroup]['days']=_combineDays(oOperatingHoursTemp[hoursGroup]['days'],hoursGroup,weekCycle); 281 weekCycle = Object.keys(oOperatingHoursTemp[hoursGroup]['days']); 282 } 283 284 $template.find(selectors.title).text(oOperatingHoursTemp[hoursGroup].name); 285 286 // clone jquery object for day/hours 287 let $dayHTML = $hoursTarget.find(selectors.day).clone(); 288 let $timeHTML = $hoursTarget.find(selectors.time).clone(); 289 290 // remove empty time/hours html 291 $hoursTarget.find(selectors.day).remove(); 292 $hoursTarget.find(selectors.time).remove(); 293 294 // loop through days of the week and add to template 295 weekCycle.forEach(function(v,i){ 296 // for readibility 297 const dayName=oOperatingHoursTemp[hoursGroup]['days'][v].name; 298 const dayOpen=oOperatingHoursTemp[hoursGroup]['days'][v].open;
299 const dayClose=oOperatingHoursTemp[hoursGroup]['days'][v].closed; 300 // const dayHours=(oOperatingHoursTemp[hoursGroup]['days'][v].status=='active') ? dayOpen+' - '+dayClose : 'Closed'; 301 302 if (oOperatingHoursTemp[hoursGroup]['days'][v].alternate /* && alternateText */) { 303 dayHours=oOperatingHoursTemp[hoursGroup]['days'][v].alternate; 304 } else if (oOperatingHoursTemp[hoursGroup]['days'][v].status=='active') { 305 dayHours=dayOpen+' - '+dayClose; 306 } else { 307 dayHours='Closed'; 308 } 309 310 // console.log(oOperatingHoursTemp[hoursGroup]['days'][v].alternate,v); 311 $hoursTarget.append($dayHTML.text(dayName).clone()) 312 $hoursTarget.append($timeHTML.text(dayHours).clone()) 313 }); 314 315 $template.html($template.html()); 316 $(target).html($template.html()); 317 } catch (error) { 318 console.error('Hours Editor Error:',error); 319 } 320 }
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.