− Add canvas support check
[KiwiIRC.git] / client / assets / 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
9e2e2fc5 6 this.has_canvas_support = !!window.CanvasRenderingContext2D;
bd85cbdb
VC
7 this.has_focus = true;
8 this.highlight_count = 0;
9
10 this.original_favicon = $('link[rel~="icon"]')[0].href;
11
12 $win.on('focus', function () {
13 that.has_focus = true;
14 that._resetHighlights();
15 });
16 $win.on('blur', function () {
17 that.has_focus = false;
18 });
19 },
20
21 newHighlight: function () {
22 var that = this;
23 if (!this.has_focus) {
24 this.highlight_count++;
9e2e2fc5
VC
25 if (this.has_canvas_support) {
26 this._drawFavicon(function(canvas) {
27 var bubbleCanvas = that._drawBubble(that.highlight_count.toString(), canvas);
28 that._refreshFavicon(bubbleCanvas.toDataURL());
29 });
30 }
bd85cbdb
VC
31 }
32 },
33
34 _resetHighlights: function () {
35 var that = this;
36 this.highlight_count = 0;
37 this._drawFavicon(function(canvas) {
38 that._refreshFavicon(canvas.toDataURL());
39 });
40 },
41
42 _drawFavicon: function (callback) {
43 var that = this,
44 context = this._createCanvas().getContext('2d'),
45 favicon_image = new Image();
46
47 // Allow cross origin resource requests
48 favicon_image.crossOrigin = 'anonymous';
49 // Trigger the load event
50 favicon_image.src = this.original_favicon;
51
52 favicon_image.onload = function() {
53 // Draw the favicon itself
54 context.drawImage(favicon_image, 0, 0, favicon_image.width, favicon_image.height);
55 callback(canvas);
56 };
57 },
58
59 _drawBubble: function (label, canvas) {
60 var letter_spacing = -1.5,
61 text_width = 0, text_height = 0,
62 context = test = canvas.getContext('2d'),
63 canvas_width = canvas.width,
64 canvas_height = canvas.height;
65
bd85cbdb
VC
66 // Setup a test canvas to get text width
67 test.font = context.font = 'bold 10px Arial';
68 test.textAlign = 'right';
9e2e2fc5 69 this._renderText(test, label, 0, 0, letter_spacing);
bd85cbdb
VC
70
71 // Calculate text width based on letter spacing and padding
72 text_width = test.measureText(label).width + letter_spacing * (label.length - 1) + 2;
73 text_height = 9;
74
75 // Set bubble parameters
76 bubbleX = canvas_width - text_width;
77 bubbleY = canvas_height - text_height;
78
79 // Draw bubble background
80 context.fillStyle = 'red';
81 context.fillRect(bubbleX, bubbleY, text_width, text_height);
82
83 // Draw the text
84 context.fillStyle = 'white';
9e2e2fc5 85 this._renderText(context, label, canvas_width - 1, canvas_height - 1, letter_spacing);
bd85cbdb
VC
86
87 return canvas;
88 },
89
90 _refreshFavicon: function (url) {
91 $('link[rel~="icon"]').remove();
92 $('<link rel="shortcut icon" href="' + url + '">').appendTo($('head'));
93 },
94
95 _createCanvas: function () {
96 canvas = document.createElement('canvas');
97 canvas.width = 16;
98 canvas.height = 16;
99
100 return canvas;
9e2e2fc5
VC
101 },
102
103 _renderText: function (context, text, x, y, letter_spacing) {
104 // A hacky solution for letter-spacing, but works well with small favicon text
105 // Modified from http://jsfiddle.net/davidhong/hKbJ4/
106 var current,
107 characters = text.split('').reverse(),
108 index = 0,
109 currentPosition = x;
110
111 while (index < text.length) {
112 current = characters[index++];
113 context.fillText(current, currentPosition, y);
114 currentPosition += (-1 * (context.measureText(current).width + letter_spacing));
115 }
116
117 return context;
bd85cbdb 118 }
0b7949de 119});