Passed
Pull Request — master (#3805)
by
unknown
17:20
created

favico.js ➔ hexToRgb   F

Complexity

Conditions 17

Size

Total Lines 12
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 17
eloc 10
dl 0
loc 12
rs 1.8
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like favico.js ➔ hexToRgb often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
/*!
2
 * @license MIT
3
 * @fileOverview Favico animations
4
 * @author Miroslav Magda, http://blog.ejci.net
5
 * @version 0.3.9
6
 */
7
8
/**
9
 * Create new favico instance
10
 * @param {Object} Options
11
 * @return {Object} Favico object
12
 * @example
13
 * var favico = new Favico({
14
 *    bgColor : '#d00',
15
 *    textColor : '#fff',
16
 *    fontFamily : 'sans-serif',
17
 *    fontStyle : 'bold',
18
 *    position : 'down',
19
 *    type : 'circle',
20
 *    animation : 'slide',
21
 *    dataUrl: function(url){},
22
 *    win: top
23
 * });
24
 */
25
(function() {
26
27
	var Favico = (function(opt) {
28
		'use strict';
29
		opt = (opt) ? opt : {};
30
		var _def = {
31
			bgColor : '#d00',
32
			textColor : '#fff',
33
			fontFamily : 'sans-serif', //Arial,Verdana,Times New Roman,serif,sans-serif,...
34
			fontStyle : 'bold', //normal,italic,oblique,bold,bolder,lighter,100,200,300,400,500,600,700,800,900
35
			type : 'circle',
36
			position : 'down', // down, up, left, leftup (upleft)
37
			animation : 'slide',
38
			elementId : false,
39
			dataUrl : false,
40
			win: window
41
		};
42
		var _opt, _orig, _h, _w, _canvas, _context, _img, _ready, _lastBadge, _running, _readyCb, _stop, _browser, _animTimeout, _drawTimeout, _doc;
43
44
		_browser = {};
45
		_browser.ff = typeof InstallTrigger != 'undefined';
0 ignored issues
show
Bug introduced by
The variable InstallTrigger seems to be never declared. If this is a global, consider adding a /** global: InstallTrigger */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
46
		_browser.chrome = !!window.chrome;
47
		_browser.opera = !!window.opera || navigator.userAgent.indexOf('Opera') >= 0;
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
48
		_browser.ie = /*@cc_on!@*/false;
49
		_browser.safari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0;
50
		_browser.supported = (_browser.chrome || _browser.ff || _browser.opera);
51
52
		var _queue = [];
53
		_readyCb = function() {
54
		};
55
		_ready = _stop = false;
56
		/**
57
		 * Initialize favico
58
		 */
59
		var init = function() {
60
			//merge initial options
61
			_opt = merge(_def, opt);
62
			_opt.bgColor = hexToRgb(_opt.bgColor);
63
			_opt.textColor = hexToRgb(_opt.textColor);
64
			_opt.position = _opt.position.toLowerCase();
65
			_opt.animation = (animation.types['' + _opt.animation]) ? _opt.animation : _def.animation;
66
67
			_doc = _opt.win.document;
68
69
			var isUp = _opt.position.indexOf('up') > -1;
70
			var isLeft = _opt.position.indexOf('left') > -1;
71
72
			//transform animation
73
			if (isUp || isLeft) {
74
				for (var i = 0; i < animation.types['' + _opt.animation].length; i++) {
75
					var step = animation.types['' + _opt.animation][i];
76
77
					if (isUp) {
78
						if (step.y < 0.6) {
79
							step.y = step.y - 0.4;
80
						} else {
81
							step.y = step.y - 2 * step.y + (1 - step.w);
82
						}
83
					}
84
85
					if (isLeft) {
86
						if (step.x < 0.6) {
87
							step.x = step.x - 0.4;
88
						} else {
89
							step.x = step.x - 2 * step.x + (1 - step.h);
90
						}
91
					}
92
93
					animation.types['' + _opt.animation][i] = step;
94
				}
95
			}
96
			_opt.type = (type['' + _opt.type]) ? _opt.type : _def.type;
97
98
			_orig = link.getIcon();
99
			//create temp canvas
100
			_canvas = document.createElement('canvas');
101
			//create temp image
102
			_img = document.createElement('img');
103
			if (_orig.hasAttribute('href')) {
104
				_img.setAttribute('crossOrigin', 'anonymous');
105
				_img.setAttribute('src', _orig.getAttribute('href'));
106
				//get width/height
107
				_img.onload = function() {
108
					_h = (_img.height > 0) ? _img.height : 32;
109
					_w = (_img.width > 0) ? _img.width : 32;
110
					_canvas.height = _h;
111
					_canvas.width = _w;
112
					_context = _canvas.getContext('2d');
113
					icon.ready();
114
				};
115
			} else {
116
				_img.setAttribute('src', '');
117
				_h = 32;
118
				_w = 32;
119
				_img.height = _h;
120
				_img.width = _w;
121
				_canvas.height = _h;
122
				_canvas.width = _w;
123
				_context = _canvas.getContext('2d');
124
				icon.ready();
125
			}
126
127
		};
128
		/**
129
		 * Icon namespace
130
		 */
131
		var icon = {};
132
		/**
133
		 * Icon is ready (reset icon) and start animation (if ther is any)
134
		 */
135
		icon.ready = function() {
136
			_ready = true;
137
			icon.reset();
138
			_readyCb();
139
		};
140
		/**
141
		 * Reset icon to default state
142
		 */
143
		icon.reset = function() {
144
			//reset
145
			if (!_ready) {
146
				return;
147
			}
148
			_queue = [];
149
			_lastBadge = false;
150
			_running = false;
151
			_context.clearRect(0, 0, _w, _h);
152
			_context.drawImage(_img, 0, 0, _w, _h);
153
			//_stop=true;
154
			link.setIcon(_canvas);
155
			//webcam('stop');
156
			//video('stop');
157
			window.clearTimeout(_animTimeout);
158
			window.clearTimeout(_drawTimeout);
159
		};
160
		/**
161
		 * Start animation
162
		 */
163
		icon.start = function() {
164
			if (!_ready || _running) {
165
				return;
166
			}
167
			var finished = function() {
168
				_lastBadge = _queue[0];
169
				_running = false;
170
				if (_queue.length > 0) {
171
					_queue.shift();
172
					icon.start();
173
				} else {
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
174
175
				}
176
			};
177
			if (_queue.length > 0) {
178
				_running = true;
179
				var run = function() {
180
					// apply options for this animation
181
					['type', 'animation', 'bgColor', 'textColor', 'fontFamily', 'fontStyle'].forEach(function(a) {
182
						if ( a in _queue[0].options) {
183
							_opt[a] = _queue[0].options[a];
184
						}
185
					});
186
					animation.run(_queue[0].options, function() {
187
						finished();
188
					}, false);
189
				};
190
				if (_lastBadge) {
191
					animation.run(_lastBadge.options, function() {
192
						run();
193
					}, true);
194
				} else {
195
					run();
196
				}
197
			}
198
		};
199
200
		/**
201
		 * Badge types
202
		 */
203
		var type = {};
204
		var options = function(opt) {
205
			opt.n = (( typeof opt.n) === 'number') ? Math.abs(opt.n | 0) : opt.n;
206
			opt.x = _w * opt.x;
207
			opt.y = _h * opt.y;
208
			opt.w = _w * opt.w;
209
			opt.h = _h * opt.h;
210
			opt.len = ("" + opt.n).length;
211
			return opt;
212
		};
213
		/**
214
		 * Generate circle
215
		 * @param {Object} opt Badge options
216
		 */
217
		type.circle = function(opt) {
218
			opt = options(opt);
219
			var more = false;
220 View Code Duplication
			if (opt.len === 2) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
221
				opt.x = opt.x - opt.w * 0.4;
222
				opt.w = opt.w * 1.4;
223
				more = true;
224
			} else if (opt.len >= 3) {
225
				opt.x = opt.x - opt.w * 0.65;
226
				opt.w = opt.w * 1.65;
227
				more = true;
228
			}
229
			_context.clearRect(0, 0, _w, _h);
230
			_context.drawImage(_img, 0, 0, _w, _h);
231
			_context.beginPath();
232
			_context.font = _opt.fontStyle + " " + Math.floor(opt.h * (opt.n > 99 ? 0.85 : 1)) + "px " + _opt.fontFamily;
233
			_context.textAlign = 'center';
234
			if (more) {
235
				_context.moveTo(opt.x + opt.w / 2, opt.y);
236
				_context.lineTo(opt.x + opt.w - opt.h / 2, opt.y);
237
				_context.quadraticCurveTo(opt.x + opt.w, opt.y, opt.x + opt.w, opt.y + opt.h / 2);
238
				_context.lineTo(opt.x + opt.w, opt.y + opt.h - opt.h / 2);
239
				_context.quadraticCurveTo(opt.x + opt.w, opt.y + opt.h, opt.x + opt.w - opt.h / 2, opt.y + opt.h);
240
				_context.lineTo(opt.x + opt.h / 2, opt.y + opt.h);
241
				_context.quadraticCurveTo(opt.x, opt.y + opt.h, opt.x, opt.y + opt.h - opt.h / 2);
242
				_context.lineTo(opt.x, opt.y + opt.h / 2);
243
				_context.quadraticCurveTo(opt.x, opt.y, opt.x + opt.h / 2, opt.y);
244
			} else {
245
				_context.arc(opt.x + opt.w / 2, opt.y + opt.h / 2, opt.h / 2, 0, 2 * Math.PI);
246
			}
247
			_context.fillStyle = 'rgba(' + _opt.bgColor.r + ',' + _opt.bgColor.g + ',' + _opt.bgColor.b + ',' + opt.o + ')';
248
			_context.fill();
249
			_context.closePath();
250
			_context.beginPath();
251
			_context.stroke();
252
			_context.fillStyle = 'rgba(' + _opt.textColor.r + ',' + _opt.textColor.g + ',' + _opt.textColor.b + ',' + opt.o + ')';
253
			//_context.fillText((more) ? '9+' : opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
254 View Code Duplication
			if (( typeof opt.n) === 'number' && opt.n > 999) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
255
				_context.fillText(((opt.n > 9999) ? 9 : Math.floor(opt.n / 1000) ) + 'k+', Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.2));
256
			} else {
257
				_context.fillText(opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
258
			}
259
			_context.closePath();
260
		};
261
		/**
262
		 * Generate rectangle
263
		 * @param {Object} opt Badge options
264
		 */
265
		type.rectangle = function(opt) {
266
			opt = options(opt);
267
			var more = false;
0 ignored issues
show
Unused Code introduced by
The variable more seems to be never used. Consider removing it.
Loading history...
268 View Code Duplication
			if (opt.len === 2) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
269
				opt.x = opt.x - opt.w * 0.4;
270
				opt.w = opt.w * 1.4;
271
				more = true;
272
			} else if (opt.len >= 3) {
273
				opt.x = opt.x - opt.w * 0.65;
274
				opt.w = opt.w * 1.65;
275
				more = true;
276
			}
277
			_context.clearRect(0, 0, _w, _h);
278
			_context.drawImage(_img, 0, 0, _w, _h);
279
			_context.beginPath();
280
			_context.font = _opt.fontStyle + " " + Math.floor(opt.h * (opt.n > 99 ? 0.9 : 1)) + "px " + _opt.fontFamily;
281
			_context.textAlign = 'center';
282
			_context.fillStyle = 'rgba(' + _opt.bgColor.r + ',' + _opt.bgColor.g + ',' + _opt.bgColor.b + ',' + opt.o + ')';
283
			_context.fillRect(opt.x, opt.y, opt.w, opt.h);
284
			_context.fillStyle = 'rgba(' + _opt.textColor.r + ',' + _opt.textColor.g + ',' + _opt.textColor.b + ',' + opt.o + ')';
285
			//_context.fillText((more) ? '9+' : opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
286 View Code Duplication
			if (( typeof opt.n) === 'number' && opt.n > 999) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
287
				_context.fillText(((opt.n > 9999) ? 9 : Math.floor(opt.n / 1000) ) + 'k+', Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.2));
288
			} else {
289
				_context.fillText(opt.n, Math.floor(opt.x + opt.w / 2), Math.floor(opt.y + opt.h - opt.h * 0.15));
290
			}
291
			_context.closePath();
292
		};
293
294
		/**
295
		 * Set badge
296
		 */
297
		var badge = function(number, opts) {
298
			opts = (( typeof opts) === 'string' ? {
299
				animation : opts
300
			} : opts) || {};
301
			_readyCb = function() {
302
				try {
303
					if ( typeof (number) === 'number' ? (number > 0) : (number !== '')) {
304
						var q = {
305
							type : 'badge',
306
							options : {
307
								n : number
308
							}
309
						};
310
						if ('animation' in opts && animation.types['' + opts.animation]) {
311
							q.options.animation = '' + opts.animation;
312
						}
313
						if ('type' in opts && type['' + opts.type]) {
314
							q.options.type = '' + opts.type;
315
						}
316
						['bgColor', 'textColor'].forEach(function(o) {
317
							if ( o in opts) {
318
								q.options[o] = hexToRgb(opts[o]);
319
							}
320
						});
321
						['fontStyle', 'fontFamily'].forEach(function(o) {
322
							if ( o in opts) {
323
								q.options[o] = opts[o];
324
							}
325
						});
326
						_queue.push(q);
327
						if (_queue.length > 100) {
328
							throw new Error('Too many badges requests in queue.');
329
						}
330
						icon.start();
331
					} else {
332
						icon.reset();
333
					}
334
				} catch(e) {
335
					throw new Error('Error setting badge. Message: ' + e.message);
336
				}
337
			};
338
			if (_ready) {
339
				_readyCb();
340
			}
341
		};
342
343
		/**
344
		 * Set image as icon
345
		 */
346
		var image = function(imageElement) {
347
			_readyCb = function() {
348
				try {
349
					var w = imageElement.width;
350
					var h = imageElement.height;
351
					var newImg = document.createElement('img');
352
					var ratio = (w / _w < h / _h) ? (w / _w) : (h / _h);
353
					newImg.setAttribute('crossOrigin', 'anonymous');
354
					newImg.setAttribute('src', imageElement.getAttribute('src'));
355
					newImg.height = (h / ratio);
356
					newImg.width = (w / ratio);
357
					_context.clearRect(0, 0, _w, _h);
358
					_context.drawImage(newImg, 0, 0, _w, _h);
359
					link.setIcon(_canvas);
360
				} catch(e) {
361
					throw new Error('Error setting image. Message: ' + e.message);
362
				}
363
			};
364
			if (_ready) {
365
				_readyCb();
366
			}
367
		};
368
		/**
369
		 * Set video as icon
370
		 */
371
		var video = function(videoElement) {
372
			_readyCb = function() {
373
				try {
374
					if (videoElement === 'stop') {
375
						_stop = true;
376
						icon.reset();
377
						_stop = false;
378
						return;
379
					}
380
					//var w = videoElement.width;
381
					//var h = videoElement.height;
382
					//var ratio = (w / _w < h / _h) ? (w / _w) : (h / _h);
383
					videoElement.addEventListener('play', function() {
384
						drawVideo(this);
385
					}, false);
386
387
				} catch(e) {
388
					throw new Error('Error setting video. Message: ' + e.message);
389
				}
390
			};
391
			if (_ready) {
392
				_readyCb();
393
			}
394
		};
395
		/**
396
		 * Set video as icon
397
		 */
398
		var webcam = function(action) {
399
			//UR
400
			if (!window.URL || !window.URL.createObjectURL) {
401
				window.URL = window.URL || {};
402
				window.URL.createObjectURL = function(obj) {
403
					return obj;
404
				};
405
			}
406
			if (_browser.supported) {
407
				var newVideo = false;
408
				navigator.getUserMedia = navigator.getUserMedia || navigator.oGetUserMedia || navigator.msGetUserMedia || navigator.mozGetUserMedia || navigator.webkitGetUserMedia;
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
409
				_readyCb = function() {
410
					try {
411
						if (action === 'stop') {
412
							_stop = true;
413
							icon.reset();
414
							_stop = false;
415
							return;
416
						}
417
						newVideo = document.createElement('video');
418
						newVideo.width = _w;
419
						newVideo.height = _h;
420
						navigator.getUserMedia({
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
421
							video : true,
422
							audio : false
423
						}, function(stream) {
424
							newVideo.src = URL.createObjectURL(stream);
0 ignored issues
show
Bug introduced by
The variable URL seems to be never declared. If this is a global, consider adding a /** global: URL */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
425
							newVideo.play();
426
							drawVideo(newVideo);
427
						}, function() {
428
						});
429
					} catch(e) {
430
						throw new Error('Error setting webcam. Message: ' + e.message);
431
					}
432
				};
433
				if (_ready) {
434
					_readyCb();
435
				}
436
			}
437
438
		};
439
440
		/**
441
		 * Draw video to context and repeat :)
442
		 */
443
		function drawVideo(video) {
444
			if (video.paused || video.ended || _stop) {
445
				return false;
446
			}
447
			//nasty hack for FF webcam (Thanks to Julian Ćwirko, [email protected])
448
			try {
449
				_context.clearRect(0, 0, _w, _h);
450
				_context.drawImage(video, 0, 0, _w, _h);
451
			} catch(e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
452
453
			}
454
			_drawTimeout = setTimeout(drawVideo, animation.duration, video);
455
			link.setIcon(_canvas);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
456
		}
457
458
		var link = {};
459
		/**
460
		 * Get icon from HEAD tag or create a new <link> element
461
		 */
462
		link.getIcon = function() {
463
			var elm = false;
0 ignored issues
show
Unused Code introduced by
The assignment to variable elm seems to be never used. Consider removing it.
Loading history...
464
			//get link element
465
			var getLink = function() {
466
				var link = _doc.getElementsByTagName('head')[0].getElementsByTagName('link');
467
				for (var l = link.length, i = (l - 1); i >= 0; i--) {
468
					if ((/(^|\s)icon(\s|$)/i).test(link[i].getAttribute('rel'))) {
469
						return link[i];
470
					}
471
				}
472
				return false;
473
			};
474
			if (_opt.element) {
475
				elm = _opt.element;
476
			} else if (_opt.elementId) {
477
				//if img element identified by elementId
478
				elm = _doc.getElementById(_opt.elementId);
479
				elm.setAttribute('href', elm.getAttribute('src'));
480
			} else {
481
				//if link element
482
				elm = getLink();
483
				if (elm === false) {
484
					elm = _doc.createElement('link');
485
					elm.setAttribute('rel', 'icon');
486
					_doc.getElementsByTagName('head')[0].appendChild(elm);
487
				}
488
			}
489
			elm.setAttribute('type', 'image/png');
490
			return elm;
491
		};
492
		link.setIcon = function(canvas) {
493
			var url = canvas.toDataURL('image/png');
494
			if (_opt.dataUrl) {
495
				//if using custom exporter
496
				_opt.dataUrl(url);
497
			}
498
			if (_opt.element) {
499
				_opt.element.setAttribute('href', url);
500
				_opt.element.setAttribute('src', url);
501
			} else if (_opt.elementId) {
502
				//if is attached to element (image)
503
				var elm = _doc.getElementById(_opt.elementId);
504
				elm.setAttribute('href', url);
505
				elm.setAttribute('src', url);
506
			} else {
507
				//if is attached to fav icon
508
				if (_browser.ff || _browser.opera) {
509
					//for FF we need to "recreate" element, atach to dom and remove old <link>
510
					//var originalType = _orig.getAttribute('rel');
511
					var old = _orig;
512
					_orig = _doc.createElement('link');
513
					//_orig.setAttribute('rel', originalType);
514
					if (_browser.opera) {
515
						_orig.setAttribute('rel', 'icon');
516
					}
517
					_orig.setAttribute('rel', 'icon');
518
					_orig.setAttribute('type', 'image/png');
519
					_doc.getElementsByTagName('head')[0].appendChild(_orig);
520
					_orig.setAttribute('href', url);
521
					if (old.parentNode) {
522
						old.parentNode.removeChild(old);
523
					}
524
				} else {
525
					_orig.setAttribute('href', url);
526
				}
527
			}
528
		};
529
530
		//http://stackoverflow.com/questions/5623838/rgb-to-hex-and-hex-to-rgb#answer-5624139
531
		//HEX to RGB convertor
532
		function hexToRgb(hex) {
533
			var shorthandRegex = /^#?([a-f\d])([a-f\d])([a-f\d])$/i;
534
			hex = hex.replace(shorthandRegex, function(m, r, g, b) {
535
				return r + r + g + g + b + b;
536
			});
537
			var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
538
			return result ? {
539
				r : parseInt(result[1], 16),
540
				g : parseInt(result[2], 16),
541
				b : parseInt(result[3], 16)
542
			} : false;
543
		}
544
545
		/**
546
		 * Merge options
547
		 */
548
		function merge(def, opt) {
549
			var mergedOpt = {};
550
			var attrname;
551
			for (attrname in def) {
552
				mergedOpt[attrname] = def[attrname];
553
			}
554
			for (attrname in opt) {
555
				mergedOpt[attrname] = opt[attrname];
556
			}
557
			return mergedOpt;
558
		}
559
560
		/**
561
		 * Cross-browser page visibility shim
562
		 * http://stackoverflow.com/questions/12536562/detect-whether-a-window-is-visible
563
		 */
564
		function isPageHidden() {
565
			return _doc.hidden || _doc.msHidden || _doc.webkitHidden || _doc.mozHidden;
566
		}
567
568
		/**
569
		 * @namespace animation
570
		 */
571
		var animation = {};
572
		/**
573
		 * Animation "frame" duration
574
		 */
575
		animation.duration = 40;
576
		/**
577
		 * Animation types (none,fade,pop,slide)
578
		 */
579
		animation.types = {};
580
		animation.types.fade = [{
581
			x : 0.4,
582
			y : 0.4,
583
			w : 0.6,
584
			h : 0.6,
585
			o : 0.0
586
		}, {
587
			x : 0.4,
588
			y : 0.4,
589
			w : 0.6,
590
			h : 0.6,
591
			o : 0.1
592
		}, {
593
			x : 0.4,
594
			y : 0.4,
595
			w : 0.6,
596
			h : 0.6,
597
			o : 0.2
598
		}, {
599
			x : 0.4,
600
			y : 0.4,
601
			w : 0.6,
602
			h : 0.6,
603
			o : 0.3
604
		}, {
605
			x : 0.4,
606
			y : 0.4,
607
			w : 0.6,
608
			h : 0.6,
609
			o : 0.4
610
		}, {
611
			x : 0.4,
612
			y : 0.4,
613
			w : 0.6,
614
			h : 0.6,
615
			o : 0.5
616
		}, {
617
			x : 0.4,
618
			y : 0.4,
619
			w : 0.6,
620
			h : 0.6,
621
			o : 0.6
622
		}, {
623
			x : 0.4,
624
			y : 0.4,
625
			w : 0.6,
626
			h : 0.6,
627
			o : 0.7
628
		}, {
629
			x : 0.4,
630
			y : 0.4,
631
			w : 0.6,
632
			h : 0.6,
633
			o : 0.8
634
		}, {
635
			x : 0.4,
636
			y : 0.4,
637
			w : 0.6,
638
			h : 0.6,
639
			o : 0.9
640
		}, {
641
			x : 0.4,
642
			y : 0.4,
643
			w : 0.6,
644
			h : 0.6,
645
			o : 1.0
646
		}];
647
		animation.types.none = [{
648
			x : 0.4,
649
			y : 0.4,
650
			w : 0.6,
651
			h : 0.6,
652
			o : 1
653
		}];
654
		animation.types.pop = [{
655
			x : 1,
656
			y : 1,
657
			w : 0,
658
			h : 0,
659
			o : 1
660
		}, {
661
			x : 0.9,
662
			y : 0.9,
663
			w : 0.1,
664
			h : 0.1,
665
			o : 1
666
		}, {
667
			x : 0.8,
668
			y : 0.8,
669
			w : 0.2,
670
			h : 0.2,
671
			o : 1
672
		}, {
673
			x : 0.7,
674
			y : 0.7,
675
			w : 0.3,
676
			h : 0.3,
677
			o : 1
678
		}, {
679
			x : 0.6,
680
			y : 0.6,
681
			w : 0.4,
682
			h : 0.4,
683
			o : 1
684
		}, {
685
			x : 0.5,
686
			y : 0.5,
687
			w : 0.5,
688
			h : 0.5,
689
			o : 1
690
		}, {
691
			x : 0.4,
692
			y : 0.4,
693
			w : 0.6,
694
			h : 0.6,
695
			o : 1
696
		}];
697
		animation.types.popFade = [{
698
			x : 0.75,
699
			y : 0.75,
700
			w : 0,
701
			h : 0,
702
			o : 0
703
		}, {
704
			x : 0.65,
705
			y : 0.65,
706
			w : 0.1,
707
			h : 0.1,
708
			o : 0.2
709
		}, {
710
			x : 0.6,
711
			y : 0.6,
712
			w : 0.2,
713
			h : 0.2,
714
			o : 0.4
715
		}, {
716
			x : 0.55,
717
			y : 0.55,
718
			w : 0.3,
719
			h : 0.3,
720
			o : 0.6
721
		}, {
722
			x : 0.50,
723
			y : 0.50,
724
			w : 0.4,
725
			h : 0.4,
726
			o : 0.8
727
		}, {
728
			x : 0.45,
729
			y : 0.45,
730
			w : 0.5,
731
			h : 0.5,
732
			o : 0.9
733
		}, {
734
			x : 0.4,
735
			y : 0.4,
736
			w : 0.6,
737
			h : 0.6,
738
			o : 1
739
		}];
740
		animation.types.slide = [{
741
			x : 0.4,
742
			y : 1,
743
			w : 0.6,
744
			h : 0.6,
745
			o : 1
746
		}, {
747
			x : 0.4,
748
			y : 0.9,
749
			w : 0.6,
750
			h : 0.6,
751
			o : 1
752
		}, {
753
			x : 0.4,
754
			y : 0.9,
755
			w : 0.6,
756
			h : 0.6,
757
			o : 1
758
		}, {
759
			x : 0.4,
760
			y : 0.8,
761
			w : 0.6,
762
			h : 0.6,
763
			o : 1
764
		}, {
765
			x : 0.4,
766
			y : 0.7,
767
			w : 0.6,
768
			h : 0.6,
769
			o : 1
770
		}, {
771
			x : 0.4,
772
			y : 0.6,
773
			w : 0.6,
774
			h : 0.6,
775
			o : 1
776
		}, {
777
			x : 0.4,
778
			y : 0.5,
779
			w : 0.6,
780
			h : 0.6,
781
			o : 1
782
		}, {
783
			x : 0.4,
784
			y : 0.4,
785
			w : 0.6,
786
			h : 0.6,
787
			o : 1
788
		}];
789
		/**
790
		 * Run animation
791
		 * @param {Object} opt Animation options
792
		 * @param {Object} cb Callabak after all steps are done
793
		 * @param {Object} revert Reverse order? true|false
794
		 * @param {Object} step Optional step number (frame bumber)
795
		 */
796
		animation.run = function(opt, cb, revert, step) {
797
			var animationType = animation.types[isPageHidden() ? 'none' : _opt.animation];
798
			if (revert === true) {
799
				step = ( typeof step !== 'undefined') ? step : animationType.length - 1;
800
			} else {
801
				step = ( typeof step !== 'undefined') ? step : 0;
802
			}
803
			cb = (cb) ? cb : function() {
804
			};
805
			if ((step < animationType.length) && (step >= 0)) {
806
				type[_opt.type](merge(opt, animationType[step]));
807
				_animTimeout = setTimeout(function() {
808
					if (revert) {
809
						step = step - 1;
810
					} else {
811
						step = step + 1;
812
					}
813
					animation.run(opt, cb, revert, step);
814
				}, animation.duration);
815
816
				link.setIcon(_canvas);
817
			} else {
818
				cb();
819
				return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
820
			}
821
		};
822
		//auto init
823
		init();
824
		return {
825
			badge : badge,
826
			video : video,
827
			image : image,
828
			webcam : webcam,
829
			reset : icon.reset,
830
			browser : {
831
				supported : _browser.supported
832
			}
833
		};
834
	});
835
836
	// AMD / RequireJS
837
	if ( typeof define !== 'undefined' && define.amd) {
0 ignored issues
show
Bug introduced by
The variable define seems to be never declared. If this is a global, consider adding a /** global: define */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
838
		define([], function() {
839
			return Favico;
840
		});
841
	}
842
	// CommonJS
843
	else if ( typeof module !== 'undefined' && module.exports) {
844
		module.exports = Favico;
845
	}
846
	// included directly via <script> tag
847
	else {
848
		this.Favico = Favico;
849
	}
850
851
})();
852
853
/**
854
 * @name      ElkArte Forum
855
 * @copyright ElkArte Forum contributors
856
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
857
 *
858
 * @version 1.1
859
 *
860
 * This bits acts as middle-man between the Favico and the ElkNotifications
861
 * providing the interface required by the latter.
862
 */
863
864
(function() {
865
	var ElkFavicon = (function(opt) {
866
		'use strict';
867
		opt = (opt) ? opt : {};
868
		var mentions;
869
870
		var init = function(opt) {
871
			mentions = new Favico(opt);
0 ignored issues
show
Bug introduced by
The variable Favico seems to be never declared. If this is a global, consider adding a /** global: Favico */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
872
			if (opt.number > 0)
873
				mentions.badge(opt.number);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
874
		};
875
876
		var send = function(request) {
877
			if (request.mentions > 0)
878
			{
879
				mentions.badge(request.mentions);
880
				$('#button_mentions .pm_indicator').html(request.mentions);
881
			}
882
			else
883
			{
884
				mentions.reset();
885
			}
886
		};
887
888
		init(opt);
889
		return {
890
			send: send
891
		}
892
	});
893
894
	// AMD / RequireJS
895
	if ( typeof define !== 'undefined' && define.amd) {
0 ignored issues
show
Bug introduced by
The variable define seems to be never declared. If this is a global, consider adding a /** global: define */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
896
		define([], function() {
897
			return ElkFavicon;
898
		});
899
	}
900
	// CommonJS
901
	else if ( typeof module !== 'undefined' && module.exports) {
902
		module.exports = ElkFavicon;
903
	}
904
	// included directly via <script> tag
905
	else {
906
		this.ElkFavicon = ElkFavicon;
907
	}
908
909
})();