Merge pull request #612 from M2Ys4U/man
[KiwiIRC.git] / client / src / views / favicon.js
CommitLineData
0b7949de 1_kiwi.view.Favicon = Backbone.View.extend({
bd85cbdb
VC
2 initialize: function () {
3 var that = this,
4 $win = $(window);
5
6 this.has_focus = true;
7 this.highlight_count = 0;
bc1fda38
VC
8 // Check for html5 canvas support
9 this.has_canvas_support = !!window.CanvasRenderingContext2D;
bd85cbdb 10
bc1fda38 11 // Store the original favicon
bd85cbdb
VC
12 this.original_favicon = $('link[rel~="icon"]')[0].href;
13
277e821f
VC
14 // Create our favicon canvas
15 this._createCanvas();
16
bc1fda38 17 // Reset favicon notifications when user focuses window
bd85cbdb
VC
18 $win.on('focus', function () {
19 that.has_focus = true;
20 that._resetHighlights();
21 });
22 $win.on('blur', function () {
23 that.has_focus = false;
24 });
25 },
26
27 newHighlight: function () {
28 var that = this;
29 if (!this.has_focus) {
30 this.highlight_count++;
9e2e2fc5 31 if (this.has_canvas_support) {
447dea1c
VC
32 this._drawFavicon(function() {
33 that._drawBubble(that.highlight_count.toString());
34 that._refreshFavicon(that.canvas.toDataURL());
9e2e2fc5
VC
35 });
36 }
bd85cbdb
VC
37 }
38 },
39
40 _resetHighlights: function () {
41 var that = this;
42 this.highlight_count = 0;
aa92fb91 43 this._refreshFavicon(this.original_favicon);
bd85cbdb
VC
44 },
45
46 _drawFavicon: function (callback) {
47 var that = this,
277e821f
VC
48 canvas = this.canvas,
49 context = canvas.getContext('2d'),
bd85cbdb
VC
50 favicon_image = new Image();
51
52 // Allow cross origin resource requests
53 favicon_image.crossOrigin = 'anonymous';
54 // Trigger the load event
55 favicon_image.src = this.original_favicon;
56
57 favicon_image.onload = function() {
bc1fda38 58 // Clear canvas from prevous iteration
aa92fb91 59 context.clearRect(0, 0, canvas.width, canvas.height);
bd85cbdb 60 // Draw the favicon itself
4e726fa4 61 context.drawImage(favicon_image, 0, 0, canvas.width, canvas.height);
447dea1c 62 callback();
bd85cbdb
VC
63 };
64 },
65
447dea1c 66 _drawBubble: function (label) {
bc1fda38 67 var letter_spacing,
7c87efb2 68 bubble_width = 0, bubble_height = 0,
277e821f
VC
69 canvas = this.canvas,
70 context = test_context = canvas.getContext('2d'),
bd85cbdb
VC
71 canvas_width = canvas.width,
72 canvas_height = canvas.height;
73
bc1fda38
VC
74 // Different letter spacing for MacOS
75 if (navigator.appVersion.indexOf("Mac") !== -1) {
76 letter_spacing = -1.5;
77 }
78 else {
79 letter_spacing = -1;
80 }
81
bd85cbdb 82 // Setup a test canvas to get text width
277e821f
VC
83 test_context.font = context.font = 'bold 10px Arial';
84 test_context.textAlign = 'right';
85 this._renderText(test_context, label, 0, 0, letter_spacing);
bd85cbdb 86
7c87efb2 87 // Calculate bubble width based on letter spacing and padding
277e821f 88 bubble_width = test_context.measureText(label).width + letter_spacing * (label.length - 1) + 2;
7c87efb2
VC
89 // Canvas does not have any way of measuring text height, so we just do it manually and add 1px top/bottom padding
90 bubble_height = 9;
bd85cbdb 91
7c87efb2
VC
92 // Set bubble coordinates
93 bubbleX = canvas_width - bubble_width;
94 bubbleY = canvas_height - bubble_height;
bd85cbdb
VC
95
96 // Draw bubble background
97 context.fillStyle = 'red';
7c87efb2 98 context.fillRect(bubbleX, bubbleY, bubble_width, bubble_height);
bd85cbdb
VC
99
100 // Draw the text
101 context.fillStyle = 'white';
9e2e2fc5 102 this._renderText(context, label, canvas_width - 1, canvas_height - 1, letter_spacing);
bd85cbdb
VC
103 },
104
105 _refreshFavicon: function (url) {
106 $('link[rel~="icon"]').remove();
107 $('<link rel="shortcut icon" href="' + url + '">').appendTo($('head'));
108 },
109
277e821f
VC
110 _createCanvas: function () {
111 var canvas = document.createElement('canvas');
aa92fb91
VC
112 canvas.width = 16;
113 canvas.height = 16;
277e821f
VC
114
115 this.canvas = canvas;
9e2e2fc5
VC
116 },
117
118 _renderText: function (context, text, x, y, letter_spacing) {
119 // A hacky solution for letter-spacing, but works well with small favicon text
120 // Modified from http://jsfiddle.net/davidhong/hKbJ4/
121 var current,
122 characters = text.split('').reverse(),
123 index = 0,
124 currentPosition = x;
125
126 while (index < text.length) {
127 current = characters[index++];
128 context.fillText(current, currentPosition, y);
129 currentPosition += (-1 * (context.measureText(current).width + letter_spacing));
130 }
131
132 return context;
bd85cbdb 133 }
c97214a7 134});