/mig/images/widget-deps/epiclock-2.2.3/jquery.epiclock.js
JavaScript | 504 lines | 403 code | 49 blank | 52 comment | 71 complexity | 0d4e0975fcecf6c14f58e51d0df34092 MD5 | raw file
Possible License(s): IPL-1.0, GPL-2.0, GPL-3.0, MPL-2.0-no-copyleft-exception, JSON
- /*!
- * epiClock 2.2 - Create Epic Clocks Easily
- *
- * Copyright (c) 2008 Eric Garside (http://eric.garside.name)
- * Dual licensed under:
- * MIT: http://www.opensource.org/licenses/mit-license.php
- * GPLv3: http://www.opensource.org/licenses/gpl-3.0.html
- */
- // Manager States
- var EC_HALT = 'disable', EC_RUN = 'enable', EC_KILL = 'destroy',
- // Clock Types
- EC_CLOCK = 0, EC_COUNTDOWN = 1, EC_COUNTUP = 2, EC_ROLLOVER = 3,
- EC_EXPIRE = 4, EC_LOOP = 5, EC_STOPWATCH = 6, EC_HOLDUP = 7,
- EC_EXPLICIT = 8;
-
- (function($){
-
- /**
- * Setup a placeholder for clock styles
- */
- $.epiclocks = {};
-
- var defaults = {
- epiClock: {
- offset: {
- hours: 0,
- minutes: 0,
- seconds: 0,
- days: 0,
- years: 0
- },
- arbitrary: {
- days: 0,
- years: 0
- },
- gmt: false,
- target: null,
- onTimer: null,
- onKill: null,
- onRender: function(v,val){v.html(val)},
- format: null,
- frame: {},
- dead: false,
- displace: 0,
- modifier: 0,
- variance: 0,
- daysadded: 0,
- paused: 0,
- tolerance: 0,
- selfLoc: -1,
- mode: EC_CLOCK,
- onSetup: null,
- stylesheet: null,
- containerClass: null,
- tpl: '<span></span>'
- },
- formats: [
- 'F j, Y, g:i:s a', // EC_CLOCK
- 'V{d} x{h} i{m} s{s}', // EC_COUNTDOWN
- 'Q{y} K{d} x{h} i{m} s{s}', // EC_COUNTUP
- 'V{d} x{h} i{m} s{s}', // EC_ROLLOVER
- 'x{h} i{m} s{s}', // EC_EXPIRE
- 'i{m} s{s}', // EC_LOOP
- 'x{h} C{m} s{s}', // EC_STOPWATCH
- 'Q{y} K{d} x{h} i{m} s{s}', // EC_HOLDUP
- 'F j, Y, g:i:s a' // EC_EXPLICIT
- ]
- },
- // The current mode the clock manager is in
- current = null,
- // The interval timer for the clock
- loop = null,
- // The clocks we're managing
- clocks = [];
-
- /**
- * jQuery Entry Point - CSS Loader
- *
- * Provides an interface to include stylesheets dynamically
- */
- $.cssIncludes = {};
- $.cssInclude = function(href, media){
- if ($.cssIncludes[href]) return false;
-
- $.cssIncludes[href] = true;
- media = media || 'screen';
-
- $('<link type="text/css" rel="stylesheet" href="' + href + '" media="' + media + '"/>')
- .appendTo('head');
- }
-
- /**
- * jQuery Entry Point - Clock Manager
- *
- * Provides an interface for the user to pause, destroy, or resume/start all clocks.
- */
- $.epiclock = $.fn.clocks = function(mode, precision, path){
- mode = mode || EC_RUN;
- precision = precision || 5e2;
- if (mode == current) return;
-
- switch (mode){
- case EC_KILL:
- $.each(clocks, function(){
- this.epiclock('kill')
- })
- clocks = [];
- case EC_HALT:
- if (loop){
- clearInterval(loop);
- loop = null;
- }
-
- $.each(clocks, function(){
- this.epiclock('disable')
- })
-
- current = mode;
- break;
- case EC_RUN:
- if (!loop){
- cycleClocks(true);
- loop = setInterval(cycleClocks, precision);
- }
- current = mode;
- break;
- }
-
- return this;
- }
-
- function cycleClocks(enabled){
- process = enabled === true;
- $.each(clocks, function(i){
- if (process)
- this.epiclock('enable');
-
- this.data('epiClock').render();
- })
- }
-
- /**
- * jQuery Entry Point
- *
- * Creates the clock displays
- */
- $.fn.epiclock = function(options, predefined){
- var action = null;
-
- if (typeof options == 'string' && $.epiclocks && $.epiclocks[options])
- options = $.epiclocks[options];
- else if (predefined && $.epiclocks && $.epiclocks[predefined])
- options = $.extend(true, {}, $.epiclocks[predefined], options);
-
- switch (options){
- case 'destroy':
- action = 'kill';
- case 'disable':
- action = action||'pause';
- case 'enable':
- action = action||'resume';
- return this.each(function(){
- var ec = $(this).data('epiClock');
- if (ec instanceof epiClock) ec[ action ]();
- })
- default:
- options = $.extend(true, {}, defaults.epiClock, options);
- break;
- }
-
- this.each(function(){
- var object = $(this),
- format = (options.format || defaults.formats[options.mode]).split(''),
- isBuffering = false,
- tpl = options.tpl || defaults.tpl,
- buffer = '',
- clock = new epiClock(options, object);
-
- object.data('epiClock', clock);
- $.each(format, function(){
- x = this+'';
- switch (x){
- case ' ':
- if (!isBuffering)
- $(tpl).addClass('epiclock epiclock-spacer').appendTo(object);
- else buffer += x;
- break;
- case '{':
- isBuffering = true;
- break;
- case '}':
- isBuffering = false;
- $(tpl).addClass('epiclock').html(buffer).appendTo(object);
- buffer = '';
- break;
- default:
- // If we're buffering, this is label text
- if (isBuffering) buffer += x;
- // If it's a special character, it will be span updated
- else if (Date.prototype[x] || clock[x]) {
- clock.frame[x] = $(tpl)
- .addClass('epiclock epiclock-digit')
- .data('ec-encoding', x)
- .appendTo(object);
- }
- // If it's anything else, it's a single char label seperator
- else
- $(tpl).addClass('epiclock epiclock-separator').html(x).appendTo(object);
- break;
- }
- });
-
- clock.selfLoc = clocks.push(object) - 1;
- if ($.isFunction(clock.onSetup)) clock.onSetup.call(clock, []);
- if (clock.stylesheet) $.cssInclude(clock.stylesheet);
- if (clock.containerClass) object.addClass(clock.containerClass);
- })
-
- return this;
- }
-
- /*
- * Export the current time.
- */
- $.fn.epiclockQuery = function(format){
- var ec = $(this).data('epiClock');
-
- if (!ec)
- return "";
-
- var format = format.split(''),
- buffer = '',
- isBuffering = false,
- x = '';
-
- $.each(format, function(){
- x = this+'';
- switch (x){
- case ' ':
- buffer += x;
- break;
- case '{':
- isBuffering = true;
- break;
- case '}':
- isBuffering = false;
- break;
- default:
- // If we're buffering, this is label text
- if (isBuffering) buffer += x;
- // If it's a special character, it will be span updated
- else if (Date.prototype[x] || ec[x]) {
- buffer += ($.isFunction(ec.now[x]) ? ec.now[x]() : ec[x]()) + ''
- }
- // If it's anything else, it's a single char label seperator
- else
- buffer += x;
- break;
- }
- });
- return buffer;
- }
-
- function epiClock(options, element){
- if (this instanceof epiClock)
- return this.init(options, element);
- else return new epiClock(options, element);
- }
-
- epiClock.prototype = {
- Q: function() { return this.arbitrary.years },
- E: function() { return this.arbitrary.days },
- e: function() { return this.arbitrary.days.pad(0) },
- zero: new Date(0),
- pause: function(){
- if (this.dead) return;
- this.paused = new Date().valueOf();
- this.dead = true;
- },
- resume: function(){
- if (!this.dead) return;
- if (this.mode == EC_STOPWATCH)
- this.displace += (this.paused - new Date().valueOf());
- this.paused = 0;
- this.dead = false;
- },
- kill: function(){
- // Remove and Renumber Clocks Array
- clocks.splice(this.selfLoc,1);
- $.each(clocks, function(i){this.data('epiClock').selfLoc = i});
-
- // Call on kill, set dead
- if ($.isFunction(this.onKill)) this.onKill();
- this.dead = true;
- },
- init: function(options, element){
- if (options.mode < EC_CLOCK || options.mode > EC_EXPLICIT)
- throw 'EPICLOCK_INVALID_MODE';
-
- var clock = this;
- $.each(options, function(k, v){
- clock[k] = v;
- });
-
- switch (this.mode){
- case EC_LOOP:
- case EC_EXPIRE:
- this.target = this.target || new Date();
- case EC_COUNTDOWN:
- case EC_ROLLOVER:
- this.modifier = -1;
- this.variance = 1;
- break;
- case EC_STOPWATCH:
- this.displace += this.calculateOffset() + (-1 * new Date().valueOf());
- this.dead = true;
- this.paused = new Date().valueOf();
- return;
- case EC_HOLDUP:
- this.variance = -1;
- this.modifier = 1;
- break;
- case EC_EXPLICIT:
- this.displace = - new Date().valueOf();
- this.modifier = 1;
- this.variance = 0;
- break;
- default:
- this.modifier = 1;
- this.variance = 0;
- break;
- }
-
- if (this.gmt)
- this.normalize();
-
- switch (true){
- case this.target instanceof Date:
- this.target = this.target.valueOf();
- break;
- case typeof this.target == 'string':
- this.target = new Date(this.target).valueOf();
- break;
- }
-
- this.displace += this.modifier * this.calculateOffset();
- },
- calculateOffset: function(offset){
- offset = offset || this.offset;
- return (
- offset.years * 3157056e4 +
- offset.days * 864e5 +
- offset.hours * 36e5 +
- offset.minutes * 6e4 +
- (this.variance + offset.seconds) * 1e3
- );
- },
- normalize: function(){
- this.displace += new Date().getTimezoneOffset()*6e4;
- },
- render: function(){
- if (!this.tick()) return;
- var clock = this,
- time = (this.mode == EC_HOLDUP) ? this.zero : this.now;
- $.each(this.frame, function(k,v){
- var val = ($.isFunction(time[k]) ? time[k]() : clock[k]()) + '';
- if (v.data('last') != val) clock.onRender(v, val);
- v.data('last', val)
- })
- },
- tick: function(){
- if (this.dead) return false;
- var now = new Date().valueOf() + this.displace;
-
- switch (this.mode){
- case EC_HOLDUP:
- if (this.target < now) this.mode = EC_COUNTUP;
- case EC_COUNTUP:
- now -= this.target;
- break;
- case EC_EXPLICIT:
- now += this.target;
- break;
- case EC_ROLLOVER:
- if (now > this.target) now = now - this.target;
- else now = this.target - now;
- break;
- case EC_COUNTDOWN:
- case EC_EXPIRE:
- case EC_LOOP:
- now = this.target - now;
- if (now < this.tolerance) return this.timerEnd();
- break;
- }
-
- this.now = new Date(now);
-
- var days = this.now.V();
- if (days <= this.daysadded) return true;
-
- this.daysadded = days;
- this.arbitrary.days += days;
-
- if (this.arbitrary.days < 365) return true;
- this.arbitrary.years += Math.floor(this.arbitrary.days/365.4 % 365.4);
- this.arbitrary.days = Math.floor(this.arbitrary.days % 365.4);
-
- return true;
- },
- timerEnd: function(){
- if ($.isFunction(this.onTimer)) this.onTimer();
-
- switch (this.mode){
- case EC_COUNTDOWN:
- case EC_EXPIRE:
- this.kill();
- break;
- case EC_LOOP:
- this.displace += this.modifier * this.calculateOffset();
- return this.render();
- case EC_ROLLOVER:
- this.mode = EC_COUNTUP;
- return true;
- }
-
- this.now = new Date(0);
- return true;
- }
- };
-
- $.extend(String.prototype, {
- pad: function(s,l){ l=l||2; return this.length < l ? new Array(1+l-this.length).join(s) + this : this },
- rpad: function(s,l){ l=l||2; return this.length < l ? this + new Array(1+l-this.length).join(s) : this }
- })
-
- $.extend(Number.prototype, {
- pad: function(s,l){ return (this+'').pad(s,l) },
- rpad: function(s,l){ return (this+'').rpad(s,l) }
- })
- /** Prototype the Date function **/
- $.extend(Date.prototype, {
- // Assistance Definitions
- modCalc: function(mod1,mod2){return (Math.floor(Math.floor(this.valueOf()/1e3)/mod1)%mod2)},
- months: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
- days: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
- suffix: [null, 'st', 'nd', 'rd'],
- // Timer Functions
- V: function(){return this.modCalc(864e2,1e5)}, // Days
- v: function(){return this.V().pad(0)}, // Paded Days
- K: function(){return this.V()%365}, // Days Offset for Years
- k: function(){return this.K().pad(0)}, // Padded Offset Days
- X: function(){return this.modCalc(36e2,24)}, // Hours
- x: function(){return this.X().pad(0)}, // Padded Hours
- p: function(){return this.modCalc(60,60)}, // Minutes
- C: function(){return this.p().pad(0)}, // Padded Minutes
- // Day
- d: function() { return this.getDate().pad('0') },
- D: function() { return this.days[this.getDay()].substring(0,3) },
- j: function() { return this.getDate() },
- l: function() { return this.days[this.getDay()] },
- N: function() { return this.getDay() + 1 },
- S: function() { return this.suffix[this.getDate()] || 'th' },
- w: function() { return this.getDay() },
- z: function() { return Math.round((this-this.f())/864e5) },
- // Week
- W: function() { return Math.ceil(((((this-this.f())/864e5) + this.f().w())/7)) },
- // Month
- F: function() { return this.months[this.getMonth()]; },
- m: function() { return (this.getMonth()+1).pad(0) },
- M: function() { return this.months[this.getMonth()].substring(0,3) },
- n: function() { return this.getMonth() + 1 },
- // Year
- L: function() { var Y = this.Y(); return Y%4 ? false : Y%100 ? true : Y%400 ? false : true },
- f: function() { return new Date(this.getFullYear(),0,1) },
- Y: function() { return this.getFullYear() },
- y: function() { return ('' + this.getFullYear()).substr(2) },
- // Time
- a: function() { return this.getHours() < 12 ? 'am' : 'pm' },
- A: function() { return this.a().toUpperCase() },
- B: function() { return Math.floor((((this.getHours()) * 36e5) + (this.getMinutes() * 6e4) + (this.getSeconds() * 1e3))/864e2).pad(0,3) },
- g: function() { return this.getHours()%12 || 12 },
- G: function() { return this.getHours() },
- h: function() { return this.g().pad('0') },
- H: function() { return this.getHours().pad('0') },
- i: function() { return this.getMinutes().pad(0) },
- s: function() { return this.getSeconds().pad('0') },
- u: function() { return this.getTime()%1000 },
- // Timezone
- O: function() { var t = this.getTimezoneOffset() / 60; return (t >= 0 ? '+' : '-') + Math.abs(t).pad(0).rpad(0,4) },
- P: function() { var t = this.O(); return t.substr(0,3) + ':' + t.substr(3)},
- Z: function() { return this.getTimezoneOffset() * 60;},
- // Full Date/Time
- c: function() { return this.Y()+'-'+this.m()+'-'+this.d()+'T'+this.H()+':'+this.i()+':'+this.s()+this.P()},
- r: function() { return this.toString() },
- U: function() { return this.getTime() / 1000 }
- });
-
- })(jQuery);