}
};
+ this.notificationFavicon();
this.initSound();
},
},
+ // This will have to be rewiritten to store highlights in kiwi, and not here
+ notificationFavicon: function () {
+ var base_path = this.model.get('base_path');
+
+ this.favicon = new (function () {
+ var that = this,
+ hasFocus = true,
+ highlightCount = 0,
+ hasConvasSupport = !!window.CanvasRenderingContext2D,
+ originalTitle = document.title,
+ originalFaviconLink = $('link[rel~="icon"]')[0].href,
+ font = 'bold 10px Arial',
+ letterSpacing = -1.5;
+
+ var ua = (function () {
+ var agent = navigator.userAgent.toLowerCase();
+ return function (browser) {
+ return agent.indexOf(browser) !== -1;
+ };
+ })();
+
+ var browser = {
+ ie: ua('msie'),
+ chrome: ua('chrome'),
+ webkit: ua('chrome') || ua('safari'),
+ safari: ua('safari') && !ua('chrome'),
+ mozilla: ua('mozilla') && !ua('chrome') && !ua('safari')
+ };
+
+ this.newHighlight = function () {
+ if (!hasFocus) {
+ highlightCount++;
+ that._updateFavicon(highlightCount);
+ }
+ };
+
+ this.resetHighlights = function () {
+ highlightCount = 0;
+ that._refreshFavicon(originalFaviconLink);
+ that._setTitle();
+ }
+
+ this._updateFavicon = function (text) {
+ text = text.toString();
+ if (!hasConvasSupport || browser.ie || browser.safari) {
+ that._setTitle(text);
+ }
+ else {
+ that._drawFavicon(text);
+ }
+ };
+
+ this._drawFavicon = function (text) {
+ var context = that._createCanvas().getContext('2d'),
+ faviconImage = new Image();
+
+ // Allow cross origin resource requests
+ faviconImage.crossOrigin = 'anonymous';
+ // Trigger the load event
+ faviconImage.src = originalFaviconLink;
+
+ // Wait for the favicon image to load
+ faviconImage.onload = function () {
+ // Draw the favicon itself
+ context.drawImage(faviconImage, 0, 0, faviconImage.width, faviconImage.height);
+ // Add highlight bubble
+ that._drawBubble(context, text);
+ //Update
+ that._refreshFavicon(canvas.toDataURL());
+ };
+ };
+
+ this._drawBubble = function (context, text) {
+ var textWidth = 0, textHidth = 0,
+ test = context,
+ canvasWidth = context.canvas.width,
+ canvasHeight = context.canvas.height;
+
+ // A hacky solution for letter-spacing, but works well with small favicon text
+ CanvasRenderingContext2D.prototype.renderText = function (text, x, y, letterSpacing) {
+ if (!text || typeof text !== 'string' || text.length === 0) {
+ return;
+ }
+ if (typeof letterSpacing === 'undefined') {
+ letterSpacing = 0;
+ }
+ // letterSpacing of 0 means normal letter-spacing
+ var characters = String.prototype.split.call(text, ''),
+ index = 0,
+ current,
+ currentPosition = x,
+ align = 1;
+
+ if (this.textAlign === 'right') {
+ characters = characters.reverse();
+ align = -1;
+ } else if (this.textAlign === 'center') {
+ var totalWidth = 0;
+ for (var i = 0; i < characters.length; i++) {
+ totalWidth += (this.measureText(characters[i]).width + letterSpacing);
+ }
+ currentPosition = x - (totalWidth / 2);
+ }
+
+ while (index < text.length) {
+ current = characters[index++];
+ this.fillText(current, currentPosition, y);
+ currentPosition += (align * (this.measureText(current).width + letterSpacing));
+ }
+ }
+
+ // Setup a test canvas to get text width
+ test.font = context.font = 'bold 10px Arial';
+ test.textAlign = 'right';
+ test.renderText(text, 0, 0, letterSpacing);
+
+ // Calculate text width based on letter spacing and padding
+ textWidth = test.measureText(text).width + letterSpacing * (text.length - 1) + 2;
+ textHeight = 8;
+
+ // Set bubble parameters
+ bubbleX = canvasWidth - textWidth;
+ bubbleY = canvasHeight - textHeight;
+
+ // Draw bubble background
+ context.fillStyle = 'red';
+ context.fillRect(bubbleX, bubbleY, textWidth, textHeight);
+
+ // Draw the text
+ context.fillStyle = 'white';
+ context.renderText(text, canvasWidth - 1, canvasHeight - 1, letterSpacing);
+ };
+
+ this._refreshFavicon = function (url) {
+ // Remove existing favicon since Firefox doesn't update fivacons on href change
+ $('link[rel~="icon"]').remove();
+ // Add new favicon
+ $('<link rel="shortcut icon" href="' + url + '">').appendTo($('head'));
+ };
+
+ this._createCanvas = function () {
+ canvas = document.createElement('canvas');
+ canvas.width = 16;
+ canvas.height = 16;
+
+ return canvas;
+ };
+
+ this._setTitle = function (text) {
+ if (text) {
+ document.title = '(' + text + ') ' + originalTitle;
+ }
+ else {
+ document.title = originalTitle;
+ }
+ };
+
+ $(window).on('focus', function () {
+ hasFocus = true;
+ that.resetHighlights();
+ });
+ $(window).on('blur', function () {
+ hasFocus = false;
+ });
+ })();
+ },
+
+
barsHide: function (instant) {
var that = this;