gantt_rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,406 @@
1
+ /* http://keith-wood.name/svg.html
2
+ jQuery DOM compatibility for jQuery SVG v1.4.5.
3
+ Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.
4
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
5
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
6
+ Please attribute the author if you use it. */
7
+
8
+ (function($) { // Hide scope, no $ conflict
9
+
10
+ /* Support adding class names to SVG nodes. */
11
+ $.fn.addClass = function(origAddClass) {
12
+ return function(classNames) {
13
+ classNames = classNames || '';
14
+ return this.each(function() {
15
+ if ($.svg.isSVGElem(this)) {
16
+ var node = this;
17
+ $.each(classNames.split(/\s+/), function(i, className) {
18
+ var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));
19
+ if ($.inArray(className, classes.split(/\s+/)) == -1) {
20
+ classes += (classes ? ' ' : '') + className;
21
+ (node.className ? node.className.baseVal = classes :
22
+ node.setAttribute('class', classes));
23
+ }
24
+ });
25
+ }
26
+ else {
27
+ origAddClass.apply($(this), [classNames]);
28
+ }
29
+ });
30
+ };
31
+ }($.fn.addClass);
32
+
33
+ /* Support removing class names from SVG nodes. */
34
+ $.fn.removeClass = function(origRemoveClass) {
35
+ return function(classNames) {
36
+ classNames = classNames || '';
37
+ return this.each(function() {
38
+ if ($.svg.isSVGElem(this)) {
39
+ var node = this;
40
+ $.each(classNames.split(/\s+/), function(i, className) {
41
+ var classes = (node.className ? node.className.baseVal : node.getAttribute('class'));
42
+ classes = $.grep(classes.split(/\s+/), function(n, i) { return n != className; }).
43
+ join(' ');
44
+ (node.className ? node.className.baseVal = classes :
45
+ node.setAttribute('class', classes));
46
+ });
47
+ }
48
+ else {
49
+ origRemoveClass.apply($(this), [classNames]);
50
+ }
51
+ });
52
+ };
53
+ }($.fn.removeClass);
54
+
55
+ /* Support toggling class names on SVG nodes. */
56
+ $.fn.toggleClass = function(origToggleClass) {
57
+ return function(className, state) {
58
+ return this.each(function() {
59
+ if ($.svg.isSVGElem(this)) {
60
+ if (typeof state !== 'boolean') {
61
+ state = !$(this).hasClass(className);
62
+ }
63
+ $(this)[(state ? 'add' : 'remove') + 'Class'](className);
64
+ }
65
+ else {
66
+ origToggleClass.apply($(this), [className, state]);
67
+ }
68
+ });
69
+ };
70
+ }($.fn.toggleClass);
71
+
72
+ /* Support checking class names on SVG nodes. */
73
+ $.fn.hasClass = function(origHasClass) {
74
+ return function(className) {
75
+ className = className || '';
76
+ var found = false;
77
+ this.each(function() {
78
+ if ($.svg.isSVGElem(this)) {
79
+ var classes = (this.className ? this.className.baseVal :
80
+ this.getAttribute('class')).split(/\s+/);
81
+ found = ($.inArray(className, classes) > -1);
82
+ }
83
+ else {
84
+ found = (origHasClass.apply($(this), [className]));
85
+ }
86
+ return !found;
87
+ });
88
+ return found;
89
+ };
90
+ }($.fn.hasClass);
91
+
92
+ /* Support attributes on SVG nodes. */
93
+ $.fn.attr = function(origAttr) {
94
+ return function(name, value, type) {
95
+ if (typeof name === 'string' && value === undefined) {
96
+ var val = origAttr.apply(this, [name]);
97
+ if (val && val.baseVal && val.baseVal.numberOfItems != null) { // Multiple values
98
+ value = '';
99
+ val = val.baseVal;
100
+ if (name == 'transform') {
101
+ for (var i = 0; i < val.numberOfItems; i++) {
102
+ var item = val.getItem(i);
103
+ switch (item.type) {
104
+ case 1: value += ' matrix(' + item.matrix.a + ',' + item.matrix.b + ',' +
105
+ item.matrix.c + ',' + item.matrix.d + ',' +
106
+ item.matrix.e + ',' + item.matrix.f + ')';
107
+ break;
108
+ case 2: value += ' translate(' + item.matrix.e + ',' + item.matrix.f + ')'; break;
109
+ case 3: value += ' scale(' + item.matrix.a + ',' + item.matrix.d + ')'; break;
110
+ case 4: value += ' rotate(' + item.angle + ')'; break; // Doesn't handle new origin
111
+ case 5: value += ' skewX(' + item.angle + ')'; break;
112
+ case 6: value += ' skewY(' + item.angle + ')'; break;
113
+ }
114
+ }
115
+ val = value.substring(1);
116
+ }
117
+ else {
118
+ val = val.getItem(0).valueAsString;
119
+ }
120
+ }
121
+ return (val && val.baseVal ? val.baseVal.valueAsString : val);
122
+ }
123
+
124
+ var options = name;
125
+ if (typeof name === 'string') {
126
+ options = {};
127
+ options[name] = value;
128
+ }
129
+ return this.each(function() {
130
+ if ($.svg.isSVGElem(this)) {
131
+ for (var n in options) {
132
+ var val = ($.isFunction(options[n]) ? options[n]() : options[n]);
133
+ (type ? this.style[n] = val : this.setAttribute(n, val));
134
+ }
135
+ }
136
+ else {
137
+ origAttr.apply($(this), [name, value, type]);
138
+ }
139
+ });
140
+ };
141
+ }($.fn.attr);
142
+
143
+ /* Support removing attributes on SVG nodes. */
144
+ $.fn.removeAttr = function(origRemoveAttr) {
145
+ return function(name) {
146
+ return this.each(function() {
147
+ if ($.svg.isSVGElem(this)) {
148
+ (this[name] && this[name].baseVal ? this[name].baseVal.value = '' :
149
+ this.setAttribute(name, ''));
150
+ }
151
+ else {
152
+ origRemoveAttr.apply($(this), [name]);
153
+ }
154
+ });
155
+ };
156
+ }($.fn.removeAttr);
157
+
158
+ /* Add numeric only properties. */
159
+ $.extend($.cssNumber, {
160
+ 'stopOpacity': true,
161
+ 'strokeMitrelimit': true,
162
+ 'strokeOpacity': true
163
+ });
164
+
165
+ /* Support retrieving CSS/attribute values on SVG nodes. */
166
+ if ($.cssProps) {
167
+ $.css = function(origCSS) {
168
+ return function(elem, name, extra) {
169
+ var value = (name.match(/^svg.*/) ? $(elem).attr($.cssProps[name] || name) : '');
170
+ return value || origCSS(elem, name, extra);
171
+ };
172
+ }($.css);
173
+ }
174
+
175
+ /* Determine if any nodes are SVG nodes. */
176
+ function anySVG(checkSet) {
177
+ for (var i = 0; i < checkSet.length; i++) {
178
+ if (checkSet[i].nodeType == 1 && checkSet[i].namespaceURI == $.svg.svgNS) {
179
+ return true;
180
+ }
181
+ }
182
+ return false;
183
+ }
184
+
185
+ /* Update Sizzle selectors. */
186
+
187
+ $.expr.relative['+'] = function(origRelativeNext) {
188
+ return function(checkSet, part, isXML) {
189
+ origRelativeNext(checkSet, part, isXML || anySVG(checkSet));
190
+ };
191
+ }($.expr.relative['+']);
192
+
193
+ $.expr.relative['>'] = function(origRelativeChild) {
194
+ return function(checkSet, part, isXML) {
195
+ origRelativeChild(checkSet, part, isXML || anySVG(checkSet));
196
+ };
197
+ }($.expr.relative['>']);
198
+
199
+ $.expr.relative[''] = function(origRelativeDescendant) {
200
+ return function(checkSet, part, isXML) {
201
+ origRelativeDescendant(checkSet, part, isXML || anySVG(checkSet));
202
+ };
203
+ }($.expr.relative['']);
204
+
205
+ $.expr.relative['~'] = function(origRelativeSiblings) {
206
+ return function(checkSet, part, isXML) {
207
+ origRelativeSiblings(checkSet, part, isXML || anySVG(checkSet));
208
+ };
209
+ }($.expr.relative['~']);
210
+
211
+ $.expr.find.ID = function(origFindId) {
212
+ return function(match, context, isXML) {
213
+ return ($.svg.isSVGElem(context) ?
214
+ [context.ownerDocument.getElementById(match[1])] :
215
+ origFindId(match, context, isXML));
216
+ };
217
+ }($.expr.find.ID);
218
+
219
+ var div = document.createElement('div');
220
+ div.appendChild(document.createComment(''));
221
+ if (div.getElementsByTagName('*').length > 0) { // Make sure no comments are found
222
+ $.expr.find.TAG = function(match, context) {
223
+ var results = context.getElementsByTagName(match[1]);
224
+ if (match[1] === '*') { // Filter out possible comments
225
+ var tmp = [];
226
+ for (var i = 0; results[i] || results.item(i); i++) {
227
+ if ((results[i] || results.item(i)).nodeType === 1) {
228
+ tmp.push(results[i] || results.item(i));
229
+ }
230
+ }
231
+ results = tmp;
232
+ }
233
+ return results;
234
+ };
235
+ }
236
+
237
+ $.expr.preFilter.CLASS = function(match, curLoop, inplace, result, not, isXML) {
238
+ match = ' ' + match[1].replace(/\\/g, '') + ' ';
239
+ if (isXML) {
240
+ return match;
241
+ }
242
+ for (var i = 0, elem = {}; elem != null; i++) {
243
+ elem = curLoop[i];
244
+ if (!elem) {
245
+ try {
246
+ elem = curLoop.item(i);
247
+ }
248
+ catch (e) {
249
+ // Ignore
250
+ }
251
+ }
252
+ if (elem) {
253
+ var className = (!$.svg.isSVGElem(elem) ? elem.className :
254
+ (elem.className ? elem.className.baseVal : '') || elem.getAttribute('class'));
255
+ if (not ^ (className && (' ' + className + ' ').indexOf(match) > -1)) {
256
+ if (!inplace)
257
+ result.push(elem);
258
+ }
259
+ else if (inplace) {
260
+ curLoop[i] = false;
261
+ }
262
+ }
263
+ }
264
+ return false;
265
+ };
266
+
267
+ $.expr.filter.CLASS = function(elem, match) {
268
+ var className = (!$.svg.isSVGElem(elem) ? elem.className :
269
+ (elem.className ? elem.className.baseVal : elem.getAttribute('class')));
270
+ return (' ' + className + ' ').indexOf(match) > -1;
271
+ };
272
+
273
+ $.expr.filter.ATTR = function(origFilterAttr) {
274
+ return function(elem, match) {
275
+ var handler = null;
276
+ if ($.svg.isSVGElem(elem)) {
277
+ handler = match[1];
278
+ $.expr.attrHandle[handler] = function(elem){
279
+ var attr = elem.getAttribute(handler);
280
+ return attr && attr.baseVal || attr;
281
+ };
282
+ }
283
+ var filter = origFilterAttr(elem, match);
284
+ if (handler) {
285
+ $.expr.attrHandle[handler] = null;
286
+ }
287
+ return filter;
288
+ };
289
+ }($.expr.filter.ATTR);
290
+
291
+ /*
292
+ In the removeData function (line 1881, v1.7.2):
293
+
294
+ if ( jQuery.support.deleteExpando ) {
295
+ delete elem[ internalKey ];
296
+ } else {
297
+ try { // SVG
298
+ elem.removeAttribute( internalKey );
299
+ } catch (e) {
300
+ elem[ internalKey ] = null;
301
+ }
302
+ }
303
+
304
+ In the event.add function (line 2985, v1.7.2):
305
+
306
+ if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
307
+ // Bind the global event handler to the element
308
+ try { // SVG
309
+ elem.addEventListener( type, eventHandle, false );
310
+ } catch(e) {
311
+ if ( elem.attachEvent ) {
312
+ elem.attachEvent( "on" + type, eventHandle );
313
+ }
314
+ }
315
+ }
316
+
317
+ In the event.remove function (line 3074, v1.7.2):
318
+
319
+ if ( !special.teardown || special.teardown.call( elem, namespaces ) === false ) {
320
+ try { // SVG
321
+ elem.removeEventListener(type, elemData.handle, false);
322
+ }
323
+ catch (e) {
324
+ if (elem.detachEvent) {
325
+ elem.detachEvent("on" + type, elemData.handle);
326
+ }
327
+ }
328
+ }
329
+
330
+ In the event.fix function (line 3394, v1.7.2):
331
+
332
+ if (event.target.namespaceURI == 'http://www.w3.org/2000/svg') { // SVG
333
+ event.button = [1, 4, 2][event.button];
334
+ }
335
+
336
+ // Add which for click: 1 === left; 2 === middle; 3 === right
337
+ // Note: button is not normalized, so don't use it
338
+ if ( !event.which && button !== undefined ) {
339
+ event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) );
340
+ }
341
+
342
+ In the Sizzle function (line 4083, v1.7.2):
343
+
344
+ if ( toString.call(checkSet) === "[object Array]" ) {
345
+ if ( !prune ) {
346
+ results.push.apply( results, checkSet );
347
+
348
+ } else if ( context && context.nodeType === 1 ) {
349
+ for ( i = 0; checkSet[i] != null; i++ ) {
350
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && Sizzle.contains(context, checkSet[i])) ) {
351
+ results.push( set[i] || set.item(i) ); // SVG
352
+ }
353
+ }
354
+
355
+ } else {
356
+ for ( i = 0; checkSet[i] != null; i++ ) {
357
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
358
+ results.push( set[i] || set.item(i) ); // SVG
359
+ }
360
+ }
361
+ }
362
+ } else {...
363
+
364
+ In the fallback for the Sizzle makeArray function (line 4877, v1.7.2):
365
+
366
+ if ( toString.call(array) === "[object Array]" ) {
367
+ Array.prototype.push.apply( ret, array );
368
+
369
+ } else {
370
+ if ( typeof array.length === "number" ) {
371
+ for ( var l = array.length; i &lt; l; i++ ) {
372
+ ret.push( array[i] || array.item(i) ); // SVG
373
+ }
374
+
375
+ } else {
376
+ for ( ; array[i]; i++ ) {
377
+ ret.push( array[i] );
378
+ }
379
+ }
380
+ }
381
+
382
+ In the jQuery.cleandata function (line 6538, v1.7.2):
383
+
384
+ if ( deleteExpando ) {
385
+ delete elem[ jQuery.expando ];
386
+
387
+ } else {
388
+ try { // SVG
389
+ elem.removeAttribute( jQuery.expando );
390
+ } catch (e) {
391
+ // Ignore
392
+ }
393
+ }
394
+
395
+ In the fallback getComputedStyle function (line 6727, v1.7.2):
396
+
397
+ defaultView = (elem.ownerDocument ? elem.ownerDocument.defaultView : elem.defaultView); // SVG
398
+ if ( defaultView &&
399
+ (computedStyle = defaultView.getComputedStyle( elem, null )) ) {
400
+
401
+ ret = computedStyle.getPropertyValue( name );
402
+ ...
403
+
404
+ */
405
+
406
+ })(jQuery);
@@ -0,0 +1,7 @@
1
+ /* http://keith-wood.name/svg.html
2
+ jQuery DOM compatibility for jQuery SVG v1.4.5.
3
+ Written by Keith Wood (kbwood{at}iinet.com.au) April 2009.
4
+ Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and
5
+ MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses.
6
+ Please attribute the author if you use it. */
7
+ eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(7($){$.q.S=7(e){8 7(d){d=d||\'\';8 9.w(7(){k($.r.v(9)){l c=9;$.w(d.E(/\\s+/),7(i,a){l b=(c.o?c.o.p:c.B(\'z\'));k($.T(a,b.E(/\\s+/))==-1){b+=(b?\' \':\'\')+a;(c.o?c.o.p=b:c.H(\'z\',b))}})}x{e.A($(9),[d])}})}}($.q.S);$.q.U=7(e){8 7(d){d=d||\'\';8 9.w(7(){k($.r.v(9)){l c=9;$.w(d.E(/\\s+/),7(i,a){l b=(c.o?c.o.p:c.B(\'z\'));b=$.1d(b.E(/\\s+/),7(n,i){8 n!=a}).1e(\' \');(c.o?c.o.p=b:c.H(\'z\',b))})}x{e.A($(9),[d])}})}}($.q.U);$.q.V=7(c){8 7(a,b){8 9.w(7(){k($.r.v(9)){k(M b!==\'1f\'){b=!$(9).N(a)}$(9)[(b?\'1g\':\'1h\')+\'1i\'](a)}x{c.A($(9),[a,b])}})}}($.q.V);$.q.N=7(d){8 7(b){b=b||\'\';l c=I;9.w(7(){k($.r.v(9)){l a=(9.o?9.o.p:9.B(\'z\')).E(/\\s+/);c=($.T(b,a)>-1)}x{c=(d.A($(9),[b]))}8!c});8 c}}($.q.N);$.q.O=7(h){8 7(b,c,d){k(M b===\'W\'&&c===1j){l e=h.A(9,[b]);k(e&&e.p&&e.p.X!=J){c=\'\';e=e.p;k(b==\'1k\'){F(l i=0;i<e.X;i++){l f=e.Y(i);1l(f.1m){C 1:c+=\' u(\'+f.u.a+\',\'+f.u.b+\',\'+f.u.c+\',\'+f.u.d+\',\'+f.u.e+\',\'+f.u.f+\')\';D;C 2:c+=\' 1n(\'+f.u.e+\',\'+f.u.f+\')\';D;C 3:c+=\' 1o(\'+f.u.a+\',\'+f.u.d+\')\';D;C 4:c+=\' 1p(\'+f.P+\')\';D;C 5:c+=\' 1q(\'+f.P+\')\';D;C 6:c+=\' 1r(\'+f.P+\')\';D}}e=c.1s(1)}x{e=e.Y(0).Z}}8(e&&e.p?e.p.Z:e)}l g=b;k(M b===\'W\'){g={};g[b]=c}8 9.w(7(){k($.r.v(9)){F(l n 1t g){l a=($.1u(g[n])?g[n]():g[n]);(d?9.1v[n]=a:9.H(n,a))}}x{h.A($(9),[b,c,d])}})}}($.q.O);$.q.10=7(b){8 7(a){8 9.w(7(){k($.r.v(9)){(9[a]&&9[a].p?9[a].p.1w=\'\':9.H(a,\'\'))}x{b.A($(9),[a])}})}}($.q.10);$.1x($.1y,{\'1z\':K,\'1A\':K,\'1B\':K});k($.11){$.12=7(e){8 7(a,b,c){l d=(b.1C(/^r.*/)?$(a).O($.11[b]||b):\'\');8 d||e(a,b,c)}}($.12)}7 G(a){F(l i=0;i<a.13;i++){k(a[i].14==1&&a[i].1D==$.r.1E){8 K}}8 I}$.m.y[\'+\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'+\']);$.m.y[\'>\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'>\']);$.m.y[\'\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'\']);$.m.y[\'~\']=7(d){8 7(a,b,c){d(a,b,c||G(a))}}($.m.y[\'~\']);$.m.Q.15=7(d){8 7(a,b,c){8($.r.v(b)?[b.1F.1G(a[1])]:d(a,b,c))}}($.m.Q.15);l j=16.1H(\'1I\');j.1J(16.1K(\'\'));k(j.17(\'*\').13>0){$.m.Q.1L=7(a,b){l c=b.17(a[1]);k(a[1]===\'*\'){l d=[];F(l i=0;c[i]||c.L(i);i++){k((c[i]||c.L(i)).14===1){d.18(c[i]||c.L(i))}}c=d}8 c}}$.m.1M.19=7(a,b,c,d,f,g){a=\' \'+a[1].1N(/\\\\/g,\'\')+\' \';k(g){8 a}F(l i=0,t={};t!=J;i++){t=b[i];k(!t){1O{t=b.L(i)}1P(e){}}k(t){l h=(!$.r.v(t)?t.o:(t.o?t.o.p:\'\')||t.B(\'z\'));k(f^(h&&(\' \'+h+\' \').1a(a)>-1)){k(!c)d.18(t)}x k(c){b[i]=I}}}8 I};$.m.R.19=7(a,b){l c=(!$.r.v(a)?a.o:(a.o?a.o.p:a.B(\'z\')));8(\' \'+c+\' \').1a(b)>-1};$.m.R.1b=7(g){8 7(c,d){l e=J;k($.r.v(c)){e=d[1];$.m.1c[e]=7(a){l b=a.B(e);8 b&&b.p||b}}l f=g(c,d);k(e){$.m.1c[e]=J}8 f}}($.m.R.1b)})(1Q);',62,115,'|||||||function|return|this|||||||||||if|var|expr||className|baseVal|fn|svg||elem|matrix|isSVGElem|each|else|relative|class|apply|getAttribute|case|break|split|for|anySVG|setAttribute|false|null|true|item|typeof|hasClass|attr|angle|find|filter|addClass|inArray|removeClass|toggleClass|string|numberOfItems|getItem|valueAsString|removeAttr|cssProps|css|length|nodeType|ID|document|getElementsByTagName|push|CLASS|indexOf|ATTR|attrHandle|grep|join|boolean|add|remove|Class|undefined|transform|switch|type|translate|scale|rotate|skewX|skewY|substring|in|isFunction|style|value|extend|cssNumber|stopOpacity|strokeMitrelimit|strokeOpacity|match|namespaceURI|svgNS|ownerDocument|getElementById|createElement|div|appendChild|createComment|TAG|preFilter|replace|try|catch|jQuery'.split('|'),0,{}))
@@ -0,0 +1,142 @@
1
+ jQuery.fn.extend({
2
+ everyTime: function(interval, label, fn, times, belay) {
3
+ return this.each(function() {
4
+ jQuery.timer.add(this, interval, label, fn, times, belay);
5
+ });
6
+ },
7
+ oneTime: function(interval, label, fn) {
8
+ return this.each(function() {
9
+ jQuery.timer.add(this, interval, label, fn, 1);
10
+ });
11
+ },
12
+ stopTime: function(label, fn) {
13
+ return this.each(function() {
14
+ jQuery.timer.remove(this, label, fn);
15
+ });
16
+ }
17
+ });
18
+
19
+ jQuery.extend({
20
+ timer: {
21
+ guid: 1,
22
+ global: {},
23
+ regex: /^([0-9]+)\s*(.*s)?$/,
24
+ powers: {
25
+ // Yeah this is major overkill...
26
+ 'ms': 1,
27
+ 'cs': 10,
28
+ 'ds': 100,
29
+ 's': 1000,
30
+ 'das': 10000,
31
+ 'hs': 100000,
32
+ 'ks': 1000000
33
+ },
34
+ timeParse: function(value) {
35
+ if (value == undefined || value == null)
36
+ return null;
37
+ var result = this.regex.exec(jQuery.trim(value.toString()));
38
+ if (result[2]) {
39
+ var num = parseInt(result[1], 10);
40
+ var mult = this.powers[result[2]] || 1;
41
+ return num * mult;
42
+ } else {
43
+ return value;
44
+ }
45
+ },
46
+ add: function(element, interval, label, fn, times, belay) {
47
+ var counter = 0;
48
+
49
+ if (jQuery.isFunction(label)) {
50
+ if (!times)
51
+ times = fn;
52
+ fn = label;
53
+ label = interval;
54
+ }
55
+
56
+ interval = jQuery.timer.timeParse(interval);
57
+
58
+ if (typeof interval != 'number' || isNaN(interval) || interval <= 0)
59
+ return;
60
+
61
+ if (times && times.constructor != Number) {
62
+ belay = !!times;
63
+ times = 0;
64
+ }
65
+
66
+ times = times || 0;
67
+ belay = belay || false;
68
+
69
+ if (!element.$timers)
70
+ element.$timers = {};
71
+
72
+ if (!element.$timers[label])
73
+ element.$timers[label] = {};
74
+
75
+ fn.$timerID = fn.$timerID || this.guid++;
76
+
77
+ var handler = function() {
78
+ if (belay && this.inProgress)
79
+ return;
80
+ this.inProgress = true;
81
+ if ((++counter > times && times !== 0) || fn.call(element, counter) === false)
82
+ jQuery.timer.remove(element, label, fn);
83
+ this.inProgress = false;
84
+ };
85
+
86
+ handler.$timerID = fn.$timerID;
87
+
88
+ if (!element.$timers[label][fn.$timerID])
89
+ element.$timers[label][fn.$timerID] = window.setInterval(handler,interval);
90
+
91
+ if ( !this.global[label] )
92
+ this.global[label] = [];
93
+ this.global[label].push( element );
94
+
95
+ },
96
+ remove: function(element, label, fn) {
97
+ var timers = element.$timers, ret;
98
+
99
+ if ( timers ) {
100
+
101
+ if (!label) {
102
+ for ( label in timers )
103
+ this.remove(element, label, fn);
104
+ } else if ( timers[label] ) {
105
+ if ( fn ) {
106
+ if ( fn.$timerID ) {
107
+ window.clearInterval(timers[label][fn.$timerID]);
108
+ delete timers[label][fn.$timerID];
109
+ }
110
+ } else {
111
+ for ( var fn in timers[label] ) {
112
+ window.clearInterval(timers[label][fn]);
113
+ delete timers[label][fn];
114
+ }
115
+ }
116
+
117
+ for ( ret in timers[label] ) break;
118
+ if ( !ret ) {
119
+ ret = null;
120
+ delete timers[label];
121
+ }
122
+ }
123
+
124
+ for ( ret in timers ) break;
125
+ if ( !ret )
126
+ element.$timers = null;
127
+ }
128
+ }
129
+ }
130
+ });
131
+
132
+ if (jQuery.browser.msie)
133
+ jQuery(window).one("unload", function() {
134
+ var global = jQuery.timer.global;
135
+ for ( var label in global ) {
136
+ var els = global[label], i = els.length;
137
+ while ( --i )
138
+ jQuery.timer.remove(els[i], label);
139
+ }
140
+ });
141
+
142
+