1/*! jCountdown jQuery Plugin - v1.5.2 - 2014-02-01 2* https://github.com/tomgrohl/jCountdown/ 3* Copyright (c) 2014 Tom Ellis; Licensed MIT */ 4/* 5 6/******************* Modified by Ignify ***********************/ 7//Modified to support multiple languages// 8/*************************************************************/ 9 10/* 11Options 12 13 dataAttr - Default null 14 Can be used instead of date option when you want to specify the date on a data-* attribute on an element. 15 Just pass the name here. 16 Example: If attribute is data-cdate, pass "cdate" 17 18 date - Default: null 19 (Must be a valid date string or Date object) 20 21 22 digits - Default: [0,1,2,3,4,5,6,7,8,9] 23 (Array of numbers used for digits in countdown) 24 25 26 direction - Default: "down" 27 Countdown Direction, "down" for down to a date, and up for "up" from a date 28 29 yearText - Default: 'years' 30 Used by template 31 32 monthText - Default: 'months' 33 Used by template 34 35 weekText - Default: 'weeks' 36 Used by template 37 38 dayText - Default: 'days' 39 Used by template 40 41 hourText - Default: 'hours' 42 Used by template 43 44 minText - Default: 'mins' 45 Used by template 46 47 secText - Default: 'sec' 48 Used by template 49 50 yearSingularText - Default: 'year' 51 Used by template 52 53 monthSingularText - Default: 'month' 54 Used by template 55 56 weekSingularText - Default: 'week' 57 Used by template 58 59 daySingularText - Default: 'day' 60 Used by template 61 62 hourSingularText - Default: 'hour' 63 Used by template 64 65 minText - Default: 'min' 66 Used by template 67 68 secText - Default: 'sec' 69 Used by template 70 71 timeWrapElement - Default: 'span' 72 Used by template for building countdown 73 74 textWrapElement - Default: 'span' 75 Used by template for building countdown 76 77 timeWrapClass - Default: '' 78 Used by template for building countdown so you can style your countdown 79 80 textWrapClass - Default: 'cd-time' 81 Used by template for building countdown so you can style your countdown 82 83 timeSeparator - Default: '' 84 (String) Separator for each time section 85 86 spaceCharacter - Default: ' ' 87 (String) Character for spacing between time, text, and separators 88 89 yearsAndMonths - Default: false 90 (Boolean. If set to true, jCountdown counts down the years/months as well) 91 92 ***The 3 options below shouldn't be used together*** 93 94 hoursOnly - Default: false 95 (Boolean. If set to true, jCountdown ignores days left and add converts to hours and adds this to the hours left) 96 97 minsOnly - Default: false 98 (Boolean. If set to true, jCountdown ignores days/hours and add converts to minutes and adds this to the minutes left) 99 100 secsOnly - Default: false 101 (Boolean. If set to true, jCountdown ignores days/hours/minutes left and converts to seconds and adds this to seconds left) 102 103 weeks - Default: false 104 (Boolean. When set to true, after months left are calculated, weeks left will be calculated.) 105 106 updateTime - Default: 1000 107 (Interval in milliseconds when the Countdown should update the time) 108 109 minus - Default: false 110 (Boolean. Whether the Countdown should have to go into minus figures, especially when counting down to a date) 111 112 onStart - Default: null 113 (Callback function for when the Countdown first starts) 114 115 onChange - Default: null 116 (Callback function for when the Countdown time updates) 117 118 onLocaleChange - Default: null 119 (Callback function for when the Countdown locale is changed) 120 121 onComplete - Default: null 122 (Callback function for when the Countdown time updates) 123 124 onPause - Default: null 125 (Callback function for when the Countdown Plugin is paused ) 126 127 onResume - Default: null 128 (Callback function for when the Countdown Plugin is resumed from pause) 129 130 leadingZero - Default: false 131 (Boolean. Whether time values should have a leading zero for values < 10. e.g 09) 132 133 omitZero - Default: false 134 (When set to true, if one of the time values is 0, it will be hidden) 135 136 offset - Default: null 137 int or float (Offset in hours, can be used for setting countdown time to match server time) 138 139 serverDiff - Default: null 140 int (servertime in milliseconds, e.g (time() * 1000) 141 142 stopwatch - Default: false 143 (Boolean. When set to true, when has countdown is resumed from being paused, it carries on from the date it paused at, not the date it resumes from.) 144 145 isRTL - Default: false 146 (Boolean). Set to true when using a Right-To-Left language 147 148 template - Default: null 149 Tokens available: %y = years, %m = months, %w = weeks, %d = days, %h = hours, %i = minutes, %s = seconds 150 151## Methods 152 153 changeLocale (since 1.5.0) - Accepts a string 154 Example: $("#time").countdown("changeLocale", "fr"); 155 156 changeSettings - Accepts an object map, the same as when first initialising the plugin 157 Example: $("#time").countdown("changeSettings", options); 158 159 getSettings - Returns setting/settings from countdown plugin, as well as the timer 160 Example: var currentSettings = $("#time").countdown("getSettings"); 161 Example: var dateSetting = $("#time").countdown("getSettings", "date"); 162 163 resume - Resumes the countdown, if previously pauses, otherwise this method does nothing 164 Example: $("#time").countdown("resume"); 165 166 pause - Pauses the countdown, simple as 167 Example: $("#time").countdown("pause"); 168 169 complete - Triggers the complete event and ends the countdown early. Also removes timer and unbinds any events. 170 Example: $("#time").countdown("complete"); 171 172 destroy - Removes timer and unbinds any events, puts the DOM Element back to its original HTML
172state 173 Example: $("#time").countdown("destroy"); 174 175 176 Settings you can access in all events through settings object: 177 178 daysLeft 179 hrsLeft 180 minsLeft 181 secLeft 182 timer (id for Interval) 183 offset 184 updateTime 185 hoursOnly (boolean) 186 yearsAndMonths (boolean) 187 date 188 minus (boolean) 189 htmlTemplate 190 191## Events - (since 1.4.2) 192 193You can bind/unbind to these events using .on and .off() 194 195 - countStart 196 - countChange 197 - countComplete 198 - countPause 199 - countResume 200 - localeChange 201 202## Usage 203 204javascript 205 206//Simple 207$(document).ready(function(){ 208 $("#time").countdown({ 209 "date" : "july 30, 2011" 210 }); 211}); 212*/ 213(function ($) { 214 $.fn.countdown = function (method /*, options*/) { 215 216 var msPerHr = 3600000, 217 secPerYear = 31557600, 218 secPerMonth = 2629800, 219 secPerWeek = 604800, 220 secPerDay = 86400, 221 secPerHr = 3600, 222 secPerMin = 60, 223 secPerSec = 1, 224 rTemplateTokens = /%y|%m|%w|%d|%h|%i|%s/g, 225 rDigitGlobal = /\d/g, 226 localNumber = function (numToConvert, settings) { 227 228 var arr = numToConvert.toString().match(rDigitGlobal), 229 localeNumber = ""; 230 231 $.each(arr, function (i, num) { 232 num = Number(num); 233 localeNumber += ("" + settings.digits[num]) || "" + num; 234 }); 235 236 return localeNumber; 237 }, 238 generateTemplateCustom = function (settings) { 239 var template = settings.template, 240 $parent = $('<div>'), 241 $timeWrapElement = settings.dom.$time.addClass(settings.timeWrapClass), 242 $textWrapElement = $("<" + settings.textWrapElement + ">").addClass(settings.textWrapClass), 243 244 sep = settings.timeSeparator, 245 246 yearsLeft = settings.yearsLeft, 247 monthsLeft = settings.monthsLeft, 248 weeksLeft = settings.weeksLeft, 249 daysLeft = settings.daysLeft, 250 hrsLeft = settings.hrsLeft, 251 minsLeft = settings.minsLeft, 252 secLeft = settings.secLeft, 253 254 hideYears = false, 255 hideMonths = false, 256 hideWeeks = false, 257 hideDays = false, 258 hideHours = false, 259 hideMins = false, 260 hideSecs = false, 261 timeTasks = [], 262 formatTime = function (time, text, showSeparator) { 263 var timeStr = $timeWrapElement.clone().html(time + settings.spaceCharacter).html(); 264 timeStr += $textWrapElement.clone().html(text + settings.spaceCharacter).html(); 265 if (showSeparator) { 266 timeStr += $textWrapElement.clone().html(settings.spaceCharacter + sep + settings.spaceCharacter).html(); 267 } 268 return timeStr; 269 }; 270 271 if (settings.omitZero) { 272 273 if (settings.yearsAndMonths) { 274 275 if (!settings.yearsLeft) { 276 hideYears = true; 277 } 278 if (!settings.monthsLeft) { 279 hideMonths = true; 280 } 281 } 282 283 if (settings.weeks && ((settings.yearsAndMonths && hideMonths && !settings.weeksLeft) || (!settings.yearsAndMonths && !settings.weeksLeft))) { 284 hideWeeks = true; 285 } 286 287 if (hideWeeks && !daysLeft) { 288 hideDays = true; 289 } 290 291 if (hideDays && !hrsLeft) { 292 hideHours = true; 293 } 294 295 if (hideHours && !minsLeft) { 296 hideMins = true; 297 } 298 299 } 300 301 if (settings.leadingZero) { 302 303 if (yearsLeft < 10) { 304 yearsLeft = "0" + yearsLeft; 305 } 306 307 if (monthsLeft < 10) { 308 monthsLeft = "0" + monthsLeft; 309 } 310 311 if (weeksLeft < 10) { 312 weeksLeft = "0" + weeksLeft; 313 } 314 315 if (daysLeft < 10) { 316 daysLeft = "0" + daysLeft; 317 } 318 319 if (hrsLeft < 10) { 320 hrsLeft = "0" + hrsLeft; 321 } 322 323 if (minsLeft < 10) { 324 minsLeft = "0" + minsLeft; 325 } 326 327 if (secLeft < 10) { 328 secLeft = "0" + secLeft; 329 } 330 } 331 332 yearsLeft = localNumber(yearsLeft, settings); 333 monthsLeft = localNumber(monthsLeft, settings); 334 weeksLeft = localNumber(weeksLeft, settings); 335 daysLeft = localNumber(daysLeft, settings); 336 hrsLeft = localNumber(hrsLeft, settings); 337 minsLeft = localNumber(minsLeft, settings); 338 secLeft = localNumber(secLeft, settings); 339 340 if (settings.yearsAndMonths) { 341 342 if (!settings.omitZero || !hideYears) { 343 template = template.replace('%y', formatTime(yearsLeft, (yearsLeft == 1 && settings.yearSingularText) ? settings.yearSingularText : settings.yearText, true)); 344 } 345 346 //Only hide months if years is at 0 as well as months 347 if (!settings.omitZero || (!hideYears && monthsLeft) || (!hideYears && !hideMonths)) { 348 template = template.replace('%m', formatTime(monthsLeft, (monthsLeft == 1 && settings.monthSingularText) ? settings.monthSingularText : settings.monthText, true)); 349 } else { 350 template = template.replace('%m', ''); 351 } 352 353 } 354 355 if (settings.weeks && !hideWeeks) { 356 template = template.replace('%w', formatTime(weeksLeft, (weeksLeft == 1 && settings.weekSingularText) ? settings.weekSingularText : settings.weekText, true)); 357 } else { 358 template = template.replace('%w', ''); 359 } 360 361 if (!hideDays) { 362 template = template.replace('%d', formatTime(
362daysLeft, (daysLeft == 1 && settings.daySingularText) ? settings.daySingularText : settings.dayText, true)); 363 } else { 364 template = template.replace('%d', ''); 365 } 366 367 if (!hideHours) { 368 template = template.replace('%h', formatTime(hrsLeft, (hrsLeft == 1 && settings.hourSingularText) ? settings.hourSingularText : settings.hourText, true)); 369 } else { 370 template = template.replace('%h', ''); 371 } 372 373 if (!hideMins) { 374 template = template.replace('%i', formatTime(minsLeft, (minsLeft == 1 && settings.minSingularText) ? settings.minSingularText : settings.minText, true)); 375 } else { 376 template = template.replace('%i', ''); 377 } 378 379 template = template.replace('%s', formatTime(secLeft, (secLeft == 1 && settings.secSingularText) ? settings.secSingularText : settings.secText)); 380 381 // Remove un-used tokens 382 template = template.replace(rTemplateTokens, ''); 383 384 return template; 385 }, 386 generateTemplate = function (settings) { 387 388 var $parent = $('<div>'), 389 $timeWrapElement = $("<" + settings.timeWrapElement + ">").addClass(settings.timeWrapClass), 390 $textWrapElement = $("<" + settings.textWrapElement + ">").addClass(settings.textWrapClass), 391 392 sep = settings.timeSeparator, 393 394 yearsLeft = settings.yearsLeft, 395 monthsLeft = settings.monthsLeft, 396 weeksLeft = settings.weeksLeft, 397 daysLeft = settings.daysLeft, 398 hrsLeft = settings.hrsLeft, 399 minsLeft = settings.minsLeft, 400 secLeft = settings.secLeft, 401 template = settings.template, 402 hasTemplate = !!settings.template, 403 hideYears = false, 404 hideMonths = false, 405 hideWeeks = false, 406 hideDays = false, 407 hideHours = false, 408 hideMins = false, 409 hideSecs = false, 410 timeTasks = [], 411 addTime = function (time) { 412 timeTasks.push(function () { 413 $parent.append($timeWrapElement.clone().html(time + settings.spaceCharacter)); 414 }); 415 }, 416 addText = function (text) { 417 timeTasks.push(function () { 418 $parent.append($textWrapElement.clone().html(text + settings.spaceCharacter)); 419 }); 420 }, 421 addSeparator = function () { 422 timeTasks.push(function () { 423 $parent.append($textWrapElement.clone().html(settings.spaceCharacter + sep + settings.spaceCharacter)); 424 }); 425 }, 426 formatTime = function (time, text, showSeparator) { 427 var timeStr = $timeWrapElement.clone().html(time + settings.spaceCharacter).html(); 428 timeStr += $textWrapElement.clone().html(text + settings.spaceCharacter).html(); 429 if (showSeparator) { 430 timeStr += $textWrapElement.clone().html(settings.spaceCharacter + sep + settings.spaceCharacter).html(); 431 } 432 return timeStr; 433 }; 434 435 if (settings.template) { 436 return generateTemplateCustom(settings); 437 } 438 439 if (settings.omitZero) { 440 441 if (settings.yearsAndMonths) { 442 443 if (!settings.yearsLeft) { 444 hideYears = true; 445 } 446 if (!settings.monthsLeft) { 447 hideMonths = true; 448 } 449 } 450 451 if (settings.weeks && ((settings.yearsAndMonths && hideMonths && !sett
451ings.weeksLeft) || (!settings.yearsAndMonths && !settings.weeksLeft))) { 452 hideWeeks = true; 453 } 454 455 if (hideWeeks && !daysLeft) { 456 hideDays = true; 457 } 458 459 if (hideDays && !hrsLeft) { 460 hideHours = true; 461 } 462 463 if (hideHours && !minsLeft) { 464 hideMins = true; 465 } 466 467 } 468 469 if (settings.leadingZero) { 470 471 if (yearsLeft < 10) { 472 yearsLeft = "0" + yearsLeft; 473 } 474 475 if (monthsLeft < 10) { 476 monthsLeft = "0" + monthsLeft; 477 } 478 479 if (weeksLeft < 10) { 480 weeksLeft = "0" + weeksLeft; 481 } 482 483 if (daysLeft < 10) { 484 daysLeft = "0" + daysLeft; 485 } 486 487 if (hrsLeft < 10) { 488 hrsLeft = "0" + hrsLeft; 489 } 490 491 if (minsLeft < 10) { 492 minsLeft = "0" + minsLeft; 493 } 494 495 if (secLeft < 10) { 496 secLeft = "0" + secLeft; 497 } 498 } 499 500 yearsLeft = localNumber(yearsLeft, settings); 501 monthsLeft = localNumber(monthsLeft, settings); 502 weeksLeft = localNumber(weeksLeft, settings); 503 daysLeft = localNumber(daysLeft, settings); 504 hrsLeft = localNumber(hrsLeft, settings); 505 minsLeft = localNumber(minsLeft, settings); 506 secLeft = localNumber(secLeft, settings); 507 508 if (settings.yearsAndMonths) { 509 510 if (!settings.omitZero || !hideYears) { 511 512 addTime(yearsLeft); 513 addText((yearsLeft == 1 && settings.yearSingularText) ? settings.yearSingularText : settings.yearText); 514 addSeparator(); 515 516 } 517 518 //Only hide months if years is at 0 as well as months 519 if (!settings.omitZero || (!hideYears && monthsLeft) || (!hideYears && !hideMonths)) { 520 521 addTime(monthsLeft); 522 addText((monthsLeft == 1 && settings.monthSingularText) ? settings.monthSingularText : settings.monthText); 523 addSeparator(); 524 } 525 } 526 527 if (settings.weeks && !hideWeeks) { 528 addTime(weeksLeft); 529 addText((weeksLeft == 1 && settings.weekSingularText) ? settings.weekSingularText : settings.weekText); 530 addSeparator(); 531 } 532 533 if (!hideDays) { 534 addTime(daysLeft); 535 addText((daysLeft == 1 && settings.daySingularText) ? settings.daySingularText : settings.dayText); 536 addSeparator(); 537 } 538 539 if (!hideHours) { 540 addTime(hrsLeft); 541 addText((hrsLeft == 1 && settings.hourSingularText) ? settings.hourSingularText : settings.hourText); 542 addSeparator(); 543 } 544 545 if (!hideMins) { 546 addTime(minsLeft); 547 addText((minsLeft == 1 && settings.minSingularText) ? settings.minSingularText : settings.minText); 548 addSeparator(); 549 } 550 551 552 addTime(secLeft); 553 addText(settings.secText); 554 555 if (settings.isRTL === true) { 556 timeTasks.reverse(); 557 } 558 559 $.each(timeTasks, function (i, task) { 560 task(); 561 }); 562 563 template = $parent.html(); 564 565 return template; 566 }, 567 dateNow = function ($this) { 568 var now = new Date(), //Default to local time 569 settings = $this.data("jcdData"); 570 571 if (!settings) { 572 return new Date(); 573 } 574 575 if (settings.offset !== null) { 576 now = getTZDate(settings.offset); 577 } 578 579 now.setMilliseconds(0); 580 return now; 581 }, 582 getTZDate = function (offset) { 583 // Returns date now based on timezone/offset 584 var hrs, 585 dateMS, 586 curHrs, 587 tmpDate = new Date(); 588 589 if (offset !== null) { 590 hrs = offset * msPerHr; 591 curHrs = tmpDate.getTime() - ((-tmpDate.getTimezoneOffset() / 60) * msPerHr) + hrs; 592 dateMS = tmpDate.setTime(curHrs); 593 } 594 595 return new Date(dateMS); 596 },
597 timerFunc = function () { 598 //Function runs at set interval updating countdown 599 var $this = this, 600 template, 601 now, 602 date, 603 timeLeft, 604 yearsLeft = 0, 605 monthsLeft = 0, 606 weeksLeft = 0, 607 daysLeft = 0, 608 hrsLeft = 0, 609 minsLeft = 0, 610 secLeft = 0, 611 time = "", 612 diff, 613 614 hideYears = false, 615 hideMonths = false, 616 hideWeeks = false, 617 hideDays = false, 618 hideHours = false, 619 hideMins = false, 620 hideSecs = false, 621 622 extractSection = function (numSecs) { 623 var amount; 624 625 amount = Math.floor(diff / numSecs); 626 diff -= amount * numSecs; 627 628 return amount; 629 }, 630 settings = $this.data("jcdData"); 631 632 if (!settings) { 633 return false; 634 } 635 636 template = settings.htmlTemplate; 637 now = dateNow($this); 638 639 if (settings.serverDiff !== null) { 640 date = new Date(settings.serverDiff + settings.clientdateNow.getTime()); 641 } else { 642 date = settings.dateObj; //Date to countdown to 643 } 644 645 date.setMilliseconds(0); 646 647 timeLeft = (settings.direction === "down") ? date.getTime() - now.getTime() : now.getTime() - date.getTime(); 648 649 diff = Math.round(timeLeft / 1000); 650 651 daysLeft = extractSection(secPerDay); 652 hrsLeft = extractSection(secPerHr); 653 minsLeft = extractSection(secPerMin); 654 secLeft = extractSection(secPerSec); 655 656 if (settings.yearsAndMonths) { 657 658 //Add days back on so we can calculate years easier 659 diff += (daysLeft * secPerDay); 660 661 yearsLeft = extractSection(secPerYear); 662 monthsLeft = extractSection(secPerMonth); 663 daysLeft = extractSection(secPerDay); 664 } 665 666 if (settings.weeks) { 667 //Add days back on so we can calculate weeks easier 668 diff += (daysLeft * secPerDay); 669 670 weeksLeft = extractSection(secPerWeek); 671 daysLeft = extractSection(secPerDay); 672 } 673 674 /** 675 * The following 3 option should never be used together! 676 * MAKE them work for any time 677 */ 678 679 if (settings.hoursOnly || settings.minsOnly || settings.secsOnly) { 680 681 if (settings.yearsAndMonths) { 682 //Add years, months, weeks and days back on so we can calculate dates easier 683 diff += (yearsLeft * secPerYear); 684 diff += (monthsLeft * secPerMonth); 685 686 yearsLeft = monthsLeft = 0; 687 } 688 689 if (settings.weeks) { 690 diff += (weeksLeft * secPerWeek); 691 692 weeksLeft = 0; 693 } 694 695 } 696 697 //Assumes you are using dates within a month ( ~ 30 days ) 698 //as years and months aren't taken into account 699 if (settings.hoursOnly) { 700 701 // Add days back on 702 diff += (daysLeft * secPerDay); 703 704 // Add hours back on 705 diff += (hrsLeft * secPerHr); 706 hrsLeft = extractSection(secPerHr); 707 708 } 709 710 //Assumes you are only using dates in the near future ( <= 24 hours ) 711 //as years and months aren't taken into account 712 if (settings.minsOnly) { 713 714 715 // Add days back on 716 diff += (daysLeft * secPerDay); 717 daysLeft = 0; 718 719 // Add hours back on 720 diff += (hrsLeft * secPerHr); 721 hrsLeft = 0; 722 723 diff += (minsLeft * secPerMin); 724 725 minsLeft = extractSection(secPerMin); 726 727 } 728 729 //Assumes you are only using dates in the near future ( <= 60 minutes ) 730 //as years, months and days aren't taken into account 731 if (settings.secsOnly) { 732 733 734 // Add days back on 735 diff += (daysLeft * secPerDay); 736 daysLeft = 0; 737 738 // Add hours back on 739 diff += (hrsLeft * secPerHr); 740 hrsLeft = 0; 741 742 // Add minutes back on 743 diff += (minsLeft * secPerMin); 744 minsLeft = 0; 745 746 // Add seconds back on 747 diff += secLeft; 748 749 secLeft = extractSection(secPerSec); 750 } 751 752 settings.yearsLeft = yearsLeft; 753 settings.monthsLeft = monthsLeft; 754 settings.weeksLeft = weeksLeft; 755 settings.daysLeft = daysLeft; 756 settings.hrsLeft = hrsLeft; 757 settings.minsLeft = minsLeft; 758 settings.secLeft = secLeft; 759 760 $this.data("jcdData", settings); 761 762 if ((settings.direction === "down" && (now < date || settings.minus)) || (sett
762ings.direction === "up" && (date < now || settings.minus))) { 763 time = generateTemplate(settings); 764 } else { 765 settings.yearsLeft = settings.monthsLeft = settings.weeksLeft = settings.daysLeft = settings.hrsLeft = settings.minsLeft = settings.secLeft = 0; 766 767 time = generateTemplate(settings); 768 settings.hasCompleted = true; 769 } 770 771 $this.html(time).triggerMulti("change.jcdevt,countChange", [settings]); 772 773 if (settings.hasCompleted) { 774 $this.triggerMulti("complete.jcdevt,countComplete"); 775 clearInterval(settings.timer); 776 } 777 778 $this.data("jcdData", settings); 779 780 }, 781 methods = { 782 init: function (options) { 783 784 var opts = $.extend({}, $.fn.countdown.defaults, options), 785 local = null, 786 testDate, 787 testString; 788 789 return this.each(function () { 790 var $this = $(this), 791 settings = {}, 792 func; 793 794 //If this element already has a countdown timer, just change the settings 795 if ($this.data("jcdData")) { 796 $this.countdown("changeSettings", options, true); 797 opts = $this.data("jcdData"); 798 } 799 800 if (opts.date === null && opts.dataAttr === null) { 801 $.error("No Date passed to jCountdown. date option is required."); 802 return true; 803 } 804 805 if (opts.date) { 806 testString = opts.date; 807 } else { 808 testString = $this.data(opts.dataAttr); 809 } 810 811 812 testDate = new Date(testString); 813 814 if (testDate.toString() === "Invalid Date") { 815 $.error("Invalid Date passed to jCountdown: " + testString); 816 } 817 818 //Add event handlers where set 819 if (opts.onStart) { 820 $this.on("start.jcdevt", opts.onStart); 821 } 822 823 if (opts.onChange) { 824 $this.on("change.jcdevt", opts.onChange); 825 } 826 827 if (opts.onComplete) { 828 $this.on("complete.jcdevt", opts.onComplete); 829 } 830 831 if (opts.onPause) { 832 $this.on("pause.jcdevt", opts.onPause); 833 } 834 835 if (opts.onResume) { 836 $this.on("resume.jcdevt", opts.onResume); 837 } 838 839 840 if (opts.onLocaleChange) { 841 $this.on("locale.jcdevt", opts.onLocaleChange); 842 } 843 844 settings = $.extend({}, opts); 845 846 847 // Cache DOM elements for templating 848 settings.dom = {}; 849 850 settings.dom.$time = $("<" + settings.timeWrapElement + ">").addClass(settings.timeWrapClass); 851 settings.dom.$text = $("<" + settings.textWrapElement + ">").addClass(settings.textWrapClass); 852 853 settings.clientdateNow = new Date(); 854 settings.clientdateNow.setMilliseconds(0); 855 settings.originalHTML = $this.html(); 856 settings.dateObj = new Date(testString); 857 settings.dateObj.setMilliseconds(0); 858 settings.hasCompleted = false; 859 settings.timer = 0; 860 settings.yearsLeft = settings.monthsLeft = settings.weeksLeft = settings.daysLeft = settings.hrsLeft = settings.minsLeft = settings.secLeft = 0; 861 settings.difference = null; 862 863 func = $.proxy(timerFunc, $this); 864 settings.timer = setInterval(func, settings.updateTime); 865 866 $this.data("jcdData", settings).triggerMulti("start.jcdevt,countStart", [settings]); 867 868 func(); 869 }); 870 }, 871 changeSettings: function (options, internal) { 872 //Like resume but with resetting/changing options 873 return this.each(function () { 874 var $this = $(this), 875 settings, 876 testDate, 877 func = $.proxy(timerFunc, $this); 878 879 if (!$this.data("jcdData")) { 880 return true; 881 } 882 883 settings = $.extend({}, $this.data("jcdData"), options); 884 885 if (options.hasOwnProperty("date")) { 886 testDate = new Date(options.date); 887 888 if (testDate.toString() === "Invalid Date") { 889 $.error("Invalid Date passed to
889jCountdown: " + options.date); 890 } 891 } 892 893 settings.completed = false; 894 settings.dateObj = new Date(options.date); 895 896 //Clear the timer, as it might not be needed 897 clearInterval(settings.timer); 898 $this.off(".jcdevt").data("jcdData", settings); 899 900 //As this can be accessed via the init method as well, 901 //we need to check how this method is being accessed 902 if (!internal) { 903 904 if (settings.onChange) { 905 $this.on("change.jcdevt", settings.onChange); 906 } 907 908 if (settings.onComplete) { 909 $this.on("complete.jcdevt", settings.onComplete); 910 } 911 912 if (settings.onPause) { 913 $this.on("pause.jcdevt", settings.onPause); 914 } 915 916 if (settings.onResume) { 917 $this.on("resume.jcdevt", settings.onResume); 918 } 919 920 settings.timer = setInterval(func, settings.updateTime); 921 $this.data("jcdData", settings); 922 func(); //Needs to run straight away when changing settings 923 } 924 925 settings = null; 926 }); 927 }, 928 resume: function () { 929 //Resumes a countdown timer 930 return this.each(function () { 931 var $this = $(this), 932 settings = $this.data("jcdData"), 933 func = $.proxy(timerFunc, $this); 934 935 if (!settings) { 936 return true; 937 } 938 939 $this.data("jcdData", settings).triggerMulti("resume.jcdevt,countResume", [settings]); 940 //We only want to resume a countdown that hasn't finished 941 if (!settings.hasCompleted) { 942 settings.timer = setInterval(func, settings.updateTime); 943 944 if (settings.stopwatch && settings.direction === "up") { 945 946 var t = dateNow($this).getTime() - settings.pausedAt.getTime(), 947 d = new Date(); 948 d.setTime(settings.dateObj.getTime() + t); 949 950 settings.dateObj = d; //This is internal date 951 } 952 953 func(); 954 } 955 }); 956 }, 957 pause: function () { 958 //Pause a countdown timer 959 return this.each(function () { 960 var $this = $(this), 961 settings = $this.data("jcdData"); 962 963 if (!settings) { 964 return true; 965 } 966 967 if (settings.stopwatch) { 968 settings.pausedAt = dateNow($this); 969 } 970 //Clear interval (Will be started on resume) 971 clearInterval(settings.timer); 972 //Trigger pause event handler 973 $this.data("jcdData", settings).triggerMulti("pause.jcdevt,countPause", [settings]); 974 }); 975 }, 976 complete: function () { 977 return this.each(function () { 978 var $this = $(this), 979 settings = $this.data("jcdData"); 980 981 if (!settings) { 982 return true; 983 } 984 //Clear timer 985 clearInterval(settings.timer); 986 settings.hasCompleted = true; 987 //Update setting, trigger complete event handler, then unbind all events 988 //We don"t delete the settings in case they need to be checked later on 989 990 $this.data("jcdData", settings).triggerMulti("complete.jcdevt,countComplete", [settings]); 991 992 //$this.off(".jcdevt, co"); 993 994 }); 995 }, 996 destroy: function () { 997 return this.each(function () { 998 var $this = $(this), 999 settings = $this.data("jcdData"); 1000 1001 if (!settings) { 1002 return true; 1003 } 1004 //Clear timer 1005 clearInterval(settings.timer); 1006 //Unbind all events, remove data and put DOM Element back to its original state (HTML wise) 1007 $this.off(".jcdevt").removeData("jcdData").html(sett
1007ings.originalHTML); 1008 }); 1009 }, 1010 getSettings: function (name) { 1011 var $this = $(this), 1012 settings = $this.data("jcdData"); 1013 1014 //If an individual setting is required 1015 if (name && settings) { 1016 //If it exists, return it 1017 if (settings.hasOwnProperty(name)) { 1018 return settings[name]; 1019 } 1020 return undefined; 1021 } 1022 //Return all settings or undefined 1023 return settings; 1024 }, 1025 changeLocale: function (locale) { //new in v1.5.0 1026 var $this = $(this), 1027 settings = $this.data("jcdData"); 1028 1029 // If no locale exists error and return false 1030 if (!$.fn.countdown.locale[locale]) { 1031 $.error("Locale '" + locale + "' does not exist"); 1032 return false; 1033 } 1034 1035 $.extend(settings, $.fn.countdown.locale[locale]); 1036 1037 $this.data("jcdData", settings).triggerMulti("locale.jcdevt,localeChange", [settings]); 1038 1039 return true; 1040 } 1041 }; 1042 1043 if (methods[method]) { 1044 return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); 1045 } else if (typeof method === "object" || !method) { 1046 return methods.init.apply(this, arguments); 1047 } else { 1048 $.error("Method " + method + " does not exist in the jCountdown Plugin"); 1049 } 1050 }; 1051 1052 // new in v1.5.0 1053 $.fn.countdown.defaults = { 1054 date: null, 1055 dataAttr: null, 1056 updateTime: 1000, 1057 yearText: LABEL_YEARTEXT, 1058 monthText: LABEL_MONTHTEXT, 1059 weekText: LABEL_WEEKTEXT, 1060 dayText: LABEL_DAYTEXT, 1061 hourText: LABEL_HOURTEXT, 1062 minText: LABEL_MINTEXT, 1063 secText: LABEL_SECTEXT, 1064 1065 yearSingularText: LABEL_YEARSINGULARTEXT, 1066 monthSingularText: LABEL_MONTHSINGULARTEXT, 1067 weekSingularText: LABEL_WEEKSINGULARTEXT, 1068 daySingularText: LABEL_DAYSINGULARTEXT, 1069 hourSingularText: LABEL_HOURSINGULARTEXT, 1070 minSingularText: LABEL_MINSINGULARTEXT, 1071 secSingularText: LABEL_SECSINGULARTEXT, 1072 1073 digits: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 1074 timeWrapElement: 'span', 1075 textWrapElement: 'span', 1076 timeWrapClass: '', 1077 textWrapClass: 'cd-time', 1078 timeSeparator: '', 1079 isRTL: false, 1080 minus: false, 1081 onStart: null, 1082 onChange: null, 1083 onComplete: null, 1084 onResume: null, 1085 onPause: null, 1086 onLocaleChange: null, 1087 leadingZero: false, 1088 offset: null, 1089 serverDiff: null, 1090 spaceCharacter: ' ', 1091 hoursOnly: false, 1092 minsOnly: false, 1093 secsOnly: false, 1094 weeks: false, 1095 hours: false,
1096 yearsAndMonths: false, 1097 direction: "down", 1098 stopwatch: false, 1099 omitZero: false, 1100 template: null 1101 }; 1102 1103 //Create an array to store new locales 1104 // new in v1.5.0 1105 $.fn.countdown.locale = []; 1106 1107 // new in v1.5.0 1108 $.fn.triggerMulti = function (eventTypes, extraParameters) { 1109 var events = eventTypes.split(","); 1110 1111 return this.each(function () { 1112 var $this = $(this); 1113 1114 for (var i = 0; i < events.length; i++) { 1115 $this.trigger(events[i], extraParameters); 1116 } 1117 }); 1118 }; 1119 1120})(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.