1(function ($) { 2 3 //Global variables 4 var countdowns = []; 5 var countdownTimer = 0; 6 var millisecondsPerDay = 86400000; 7 var millisecondsPerHour = 3600000; 8 var millisecondsPerMinute = 60000; 9 var millisecondsPerSecond = 1000; 10 var statBeforeSchedule = 0; 11 var statDuringSchedule = 1; 12 var statAfterSchedule = 2; 13 14 function countdown(id, container, countdownEnabled, hasStartDate, startDays, startHours, startMinutes, startSeconds, hasEndDate, endDays, endHours, endMinutes, endSeconds, parentCountdownID, skipElemsToDetach, childCounters, showChildrenCounters) { 15 16 this.id = id; 17 this.container = container; 18 this.countdownEnabled = countdownEnabled; 19 this.content = null; 20 this.fullContent = null; 21 this.initializeDate = new Date(); 22 this.startDate = new Date(); 23 this.hasStartDate = hasStartDate; 24 this.endDate = new Date(); 25 this.hasEndDate = hasEndDate; 26 this.status = statDuringSchedule; 27 this.isHidden = false; 28 this.parentCountdownID = parentCountdownID; 29 this.skipElemsToDetach = skipElemsToDetach; 30 this.scheduledChildCounters = []; 31 this.nonScheduledChildCounters = []; 32 this.showingChildrenCountdowns = []; 33 this.showingChildren = []; 34 this.upcomingChildrenWithNoCountdowns = []; 35 36 if (childCounters.length > 0) { 37 this.childCounters = childCounters; 38 39 } else { 40 this.childCounters = $.grep(countdowns, function (c) { 41 return c.parentCountdownID == id 42 }); 43 } 44 45 this.showChildrenCounters = showChildrenCounters; 46 47 if (this.childCounters.length > 0) { 48 49 this.scheduledChildCounters = $.grep(this.childCounters, function (c) { 50 return (c.hasStartDate || c.hasEndDate) && c.status != statAfterSchedule 51 }) 52 53 this.nonScheduledChildCounters = $.grep(this.childCounters, function (c) { 54 return !c.hasStartDate && !c.hasEndDate 55 }) 56 57 updateChildFields(this); 58 59 if (this.nonScheduledChildCounters.length > 0) { 60 61 updateStartEndDates(this.startDate, hasStartDate, startDays, startHours, startMinutes, startSeconds, this.endDate, hasEndDate, endDays, endHours, endMinutes, endSeconds); 62 63 for (var i = 0; i < this.nonScheduledChildCounters.length; i++) { 64 var nonScheduledChildCounter = this.nonScheduledChildCounters[i]; 65 66 nonScheduledChildCounter.hasStartDate = hasStartDate; 67 nonScheduledChildCounter.startDate = this.startDate; 68 nonScheduledChildCounter.hasEndDate = hasEndDate; 69 nonScheduledChildCounter.endDate = this.endDate; 70 71 updateStatus(nonScheduledChildCounter); 72 } 73 74 } else if (this.scheduledChildCounters.length > 0) { 75 76 var startDates = this.scheduledChildCounters.map(function (ccd) { return ccd.startDate }); 77 78 this.startDate = new Date(Math.min.apply(null, startDates)); 79 updateDate(this.endDate, hasEndDate, endDays, endHours, endMinutes, endSeconds); 80 81 } else { 82 updateStartEndDates(this.startDate, hasStartDate, startDays, startHours, startMinutes, startSeconds, this.endDate, hasEndDate, endDays, endHours, endMinutes, endSeconds); 83 } 84 } else { 85 updateStartEndDates(this.startDate, hasStartDate, startDays, startHours, startMinutes, startSeconds, this.endDate, hasEndDate, endDays, endHours, endMinutes, endSeconds); 86 } 87 88 updateStatus(this); 89 90 } 91 92 function updateStatus(counter) { 93 94 counter.status = statDuringSchedule; 95 96 if (counter.hasStartDate) { 97 98 var SpanToStart = counter.startDate - new Date; 99 100 if (SpanToStart > 0) { 101 counter.status = statBeforeSchedule; 102 } 103 104 } 105 106 if (counter.hasEndDate) { 107 108 var SpanToEnd = counter.endDate - new Date; 109 110 if (SpanToEnd < 0) { 111 counter.status = statAfterSchedule; 112 } 113 114 } 115 } 116 117 function updateChildFields(counter) { 118 119 counter.showingChildren = $.grep(counter.scheduledChildCounters.concat(counter.nonScheduledChildCounters), function (c) { 120 return c.status == statDuringSchedule 121 }) 122 123 counter.showingChildrenCountdowns = $.grep(counter.childCounters, function (c) { 124 return c.status == statBeforeSchedule && c.countdownEnabled 125 }) 126 127 counter.upcomingChildrenWithNoCountdowns = $.grep(counter.scheduledChildCounters, function (c) { 128 return c.status == statBeforeSchedule && !c.countdownEnabled 129 }) 130 } 131 132 function updateStartEndDates(startDate, hasStartDate, startDays, startHours, startMinutes, startSeconds, endDate, hasEndDate, endDays, endHours, endMinutes, endSeconds) { 133 updateDate(startDate, hasStartDate, startDays, startHours, startMinutes, startSeconds); 134 updateDate(endDate, hasEndDate, endDays, endHours, endMinutes, endSeconds); 135 } 136 137 function updateDate(date, hasDate, days, hours, minutes, seconds) { 138 if (hasDate) { 139 date.setDate(date.getDate() + days); 140 date.setHours(date.getHours() + hours); 141 date.setMinutes(date.getMinutes() + minutes); 142 date.setSeconds(date.getSeconds() + seconds); 143 } 144 } 145 146 function getCountdownByID(id) { 147 var countdown; 148 $.each(countdowns, function () { 149 if (this.id == id) { 150 countdown = this; 151 } 152 }); 153 154 return countdown; 155 } 156 157 function removeCountdownByID(id) { 158 159 var countdownIndex = -1 160 161 $.each(countdowns, function (i) { 162 if (this.id == id) { 163 countdownIndex = i 164 } 165 }); 166 167 if (countdownIndex > -1) { 168 countdowns.splice(countdownIndex, 1); 169 } 170 171 if (countdowns.length == 0) { 172 clearInterval(countdownInterval); 173 countdownInterval = 0; 174 } 175 } 176 177 //Constructor 178 $.fn.panelCountdown = function (options) { 179 180 var childCounters = []; 181 182 if (options.childCounters && options.childCounters.length > 0) { 183 184 for (var i = 0; i < options.childCounters.length; i++) { 185 var counter = options.childCounters[i]; 186 187 var childCounter = new countdown(counter.id, $(this), counter.countdownEnabled, counter.hasStartDate, counter.startDays, counter.startHours, counter.startMinutes, counter.startSeconds, counter.hasEndDate, counter.endDays, counter.endHours, counter.endMinutes, counter.endSeconds, counter.parentCountdownID, counter.skipElemsToDetach, counter.childCounters, counter.showChildrenCounters); 188 189 childCounters.push(childCounter); 190 } 191 } 192 193 var counter = new countdown(options.id, $(this), options.countdownEnabled, options.hasStartDate, options.startDays, options.startHours, options.startMinutes, options.startSeconds, options.hasEndDate, options.endDays, options.endHours, options.endMinutes, options.endSeconds, options.parentCountdownID, options.skipElemsToDetach, childCounters, options.showChildrenCounters); 194 195 countdowns.push(counter); 196 197 initializeCountdown(options.id); 198 199 }; 200 201 function initializeCountdown(countdownID) { 202 203 var counter = getCountdownByID(countdownID) 204 205 switch (counter.status) { 206 case statBeforeSchedule: 207 208 var elemsToDetach = "*" 209 var contentDetached = false; 210 211 if (counter.parentCountdownID) { 212 counter.containerCssClass = counter.container.attr('class'); 213 214 if (counter.skipElemsToDetach && counter.countdownEnabled) { 215 elemsToDetach += " :not('" + counter.skipElemsToDetach + "')"; 216 } 217 } else { 218 contentDetached = adjustParentCounter(counter).contentDetached; 219 } 220 221 if (!contentDetached) { 222 counter.fullContent = counter.container.children();
223 counter.content = counter.container.children(elemsToDetach).detach(); 224 contentDetached = true; 225 } 226 227 if (counter.countdownEnabled) { 228 counter.container.append($('<div class="left countdownButtonAvailableIn">Available In</div>')); 229 counter.container.append($('<span class="buyNowButton notranslate button left countdownButton"></span>')); 230 } 231 232 if (counter.parentCountdownID && contentDetached && !counter.countdownEnabled) { 233 counter.container.removeAttr('class'); 234 } 235 236 break; 237 238 case statAfterSchedule: 239 counter.content = counter.container.children('*').detach(); 240 break; 241 } 242 243 244 if (countdownTimer == 0) { 245 countdownTimer = setInterval(countdownInterval, 500); 246 } 247 248 249 } 250 251 function countdownInterval() { 252 253 $.each(countdowns, function (i) { 254 255 var counter = countdowns[i] 256 257 if (counter != undefined) { 258 259 switch (counter.status) { 260 case statBeforeSchedule: 261 262 if (counter.countdownEnabled) { 263 264 var countdownButton = counter.container.find('.countdownButton') 265 266 if (countdownButton.length != 0) { 267 268 var timeSpan = counter.startDate - new Date(); 269 270 if (timeSpan > 0) { 271 272 var days = parseInt(timeSpan / millisecondsPerDay); 273 timeSpan -= (days * millisecondsPerDay); 274 275 var hours = parseInt(timeSpan / millisecondsPerHour); 276 timeSpan -= hours * millisecondsPerHour; 277 278 var minutes = parseInt(timeSpan / millisecondsPerMinute); 279 timeSpan -= minutes * millisecondsPerMinute 280 281 var seconds = parseInt(timeSpan / millisecondsPerSecond); 282 283 countdownButton.html(getCountdownString(days, hours, minutes, seconds)); 284 285 counter.container.show(); 286 287 } 288 289 } 290 } 291 break; 292 case statDuringSchedule: 293 294 if (!counter.isHidden) { 295 if (counter.parentCountdownID) { 296 var parentCounter = $.grep(countdowns, function (c) { return c.id == counter.parentCountdownID })[0]; 297 298 if (parentCounter) { 299 adjustParentCounter(parentCounter); 300 } 301 } 302 303 if (counter.content != null) { 304 counter.container.html(''); 305 306 if (counter.parentCountdownID) { 307 counter.container.attr('class', counter.containerCssClass); 308 } 309 310 counter.container.append(counter.fullContent); 311 counter.content = null; 312 } 313 314 counter.container.show(); 315 316 if (!counter.hasEndDate) { 317 removeCountdownByID(counter.id); 318 } 319 } 320 321 break; 322 323 case statAfterSchedule: 324 var removeCounter = true; 325 var removeCountdown = true; 326 327 if (counter.parentCountdownID) { 328 var parentCounter = $.grep(countdowns, function (c) { return c.id == counter.parentCountdownID })[0]; 329 330 if (parentCounter) { 331 var response = adjustParentCounter(parentCounter); 332 333 if (response.removeCounter == true) { 334 parentCounter.container.html(''); 335 parentCounter.container.hide(); 336 removeCountdownByID(parentCounter.id); 337 } 338 } 339 } 340 341 if (counter.isHidden) { 342 removeCountdown = false; 343 removeCounter = false; 344 } 345
346 if (removeCounter) { 347 counter.container.html(''); 348 counter.container.hide(); 349 350 if (removeCountdown) { 351 removeCountdownByID(counter.id); 352 } 353 } 354 355 break; 356 } 357 358 updateStatus(counter); 359 updateChildFields(counter); 360 361 } 362 363 }); 364 365 } 366 367 function adjustParentCounter(counter) { 368 369 var response = { contentDetached: false, removeCounter: false }; 370 371 if (counter.showingChildren.length == 0) { 372 var elemsToDetach = "*" 373 374 if (counter.upcomingChildrenWithNoCountdowns.length == 0 && counter.showingChildrenCountdowns.length > 0) { 375 if (counter.skipElemsToDetach) { 376 elemsToDetach += " :not('" + counter.skipElemsToDetach + "')"; 377 } 378 379 if (counter.showChildrenCounters) { 380 counter.countdownEnabled = false; 381 } else { 382 counter.countdownEnabled = true; 383 } 384 } 385 386 counter.fullContent = counter.container.children(); 387 counter.content = counter.container.children(elemsToDetach).detach(); 388 389 response.contentDetached = true; 390 } 391 392 counter.isHidden = counter.showingChildren.length == 0 && (counter.showingChildrenCountdowns.length > 0 || counter.upcomingChildrenWithNoCountdowns.length > 0); 393 response.removeCounter = counter.showingChildren.length == 0 && counter.showingChildrenCountdowns.length == 0 && counter.upcomingChildrenWithNoCountdowns.length == 0; 394 395 return response 396 } 397 398 function getCountdownString(days, hours, minutes, seconds) { 399 400 if (days >= 0 && hours >= 0 && minutes >= 0 && seconds >= 0) { 401 var displayDate = days+'D, '+hours+'H'; 402 403 if(days == 0){ 404 displayDate = hours+'H, '+minutes + 'M'; 405 } 406 if (hours == 0 && days == 0){ 407 displayDate = minutes + 'M, '+seconds + 'S'; 408 } 409 410 return displayDate; 411 412 } 413 else { 414 415 return '0D, 0H, 0M, 0S'; 416 417 } 418 419 } 420 421 422})(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.