mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-09-20 07:35:55 +08:00
Added Tinycon (Unread message tab's icon)
This commit is contained in:
parent
f1b3271b4d
commit
47bb848905
|
@ -172,7 +172,7 @@
|
|||
/**
|
||||
* @param {string} sTitle
|
||||
*/
|
||||
AbstractApp.prototype.setTitle = function (sTitle)
|
||||
AbstractApp.prototype.setWindowTitle = function (sTitle)
|
||||
{
|
||||
sTitle = ((Utils.isNormal(sTitle) && 0 < sTitle.length) ? sTitle + ' - ' : '') +
|
||||
Settings.settingsGet('Title') || '';
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
$ = require('$'),
|
||||
moment = require('moment'),
|
||||
SimplePace = require('SimplePace'),
|
||||
Tinycon = require('Tinycon'),
|
||||
|
||||
Enums = require('Common/Enums'),
|
||||
Globals = require('Common/Globals'),
|
||||
|
@ -1342,7 +1343,7 @@
|
|||
{
|
||||
Globals.$html.addClass('rl-user-auth');
|
||||
|
||||
this.setTitle(Translator.i18n('TITLES/LOADING'));
|
||||
this.setWindowTitle(Translator.i18n('TITLES/LOADING'));
|
||||
|
||||
//require.ensure([], function() { // require code splitting
|
||||
|
||||
|
@ -1479,6 +1480,17 @@
|
|||
_.defer(function () {
|
||||
self.initVerticalLayoutResizer(Enums.ClientSideKeyName.FolderListSize);
|
||||
});
|
||||
|
||||
if (Tinycon)
|
||||
{
|
||||
Tinycon.setOptions({
|
||||
fallback: false
|
||||
});
|
||||
|
||||
Events.sub('mailbox.inbox-unread-count', function (iCount) {
|
||||
Tinycon.setBubble(0 < iCount ? (99 < iCount ? 99 : iCount) : 0);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
LoginAdminScreen.prototype.onShow = function ()
|
||||
{
|
||||
require('App/Admin').setTitle('');
|
||||
require('App/Admin').setWindowTitle('');
|
||||
};
|
||||
|
||||
module.exports = LoginAdminScreen;
|
||||
|
|
|
@ -75,7 +75,7 @@
|
|||
|
||||
SettingsAdminScreen.prototype.onShow = function ()
|
||||
{
|
||||
require('App/Admin').setTitle('');
|
||||
require('App/Admin').setWindowTitle('');
|
||||
};
|
||||
|
||||
module.exports = SettingsAdminScreen;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
AboutUserScreen.prototype.onShow = function ()
|
||||
{
|
||||
require('App/User').setTitle('RainLoop');
|
||||
require('App/User').setWindowTitle('RainLoop');
|
||||
};
|
||||
|
||||
module.exports = AboutUserScreen;
|
||||
|
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
LoginUserScreen.prototype.onShow = function ()
|
||||
{
|
||||
require('App/User').setTitle('');
|
||||
require('App/User').setWindowTitle('');
|
||||
};
|
||||
|
||||
module.exports = LoginUserScreen;
|
||||
|
|
|
@ -45,21 +45,21 @@
|
|||
*/
|
||||
MailBoxUserScreen.prototype.oLastRoute = {};
|
||||
|
||||
MailBoxUserScreen.prototype.setNewTitle = function ()
|
||||
MailBoxUserScreen.prototype.updateWindowTitle = function ()
|
||||
{
|
||||
var
|
||||
sEmail = AccountStore.email(),
|
||||
nFoldersInboxUnreadCount = FolderStore.foldersInboxUnreadCount()
|
||||
;
|
||||
|
||||
require('App/User').setTitle(('' === sEmail ? '' :
|
||||
require('App/User').setWindowTitle(('' === sEmail ? '' : '' +
|
||||
(0 < nFoldersInboxUnreadCount ? '(' + nFoldersInboxUnreadCount + ') ' : ' ') +
|
||||
sEmail + ' - ') + Translator.i18n('TITLES/MAILBOX'));
|
||||
};
|
||||
|
||||
MailBoxUserScreen.prototype.onShow = function ()
|
||||
{
|
||||
this.setNewTitle();
|
||||
this.updateWindowTitle();
|
||||
Globals.keyScope(Enums.KeyState.MessageList);
|
||||
};
|
||||
|
||||
|
@ -112,7 +112,7 @@
|
|||
SettingsStore.layout.valueHasMutated();
|
||||
}, 50);
|
||||
|
||||
Events.sub('mailbox.inbox-unread-count', function (iCount) {
|
||||
Events.sub('mailbox.inbox-unread-count', _.bind(function (iCount) {
|
||||
|
||||
FolderStore.foldersInboxUnreadCount(iCount);
|
||||
|
||||
|
@ -124,12 +124,10 @@
|
|||
oItem.count(iCount);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
FolderStore.foldersInboxUnreadCount.subscribe(function () {
|
||||
this.setNewTitle();
|
||||
}, this);
|
||||
this.updateWindowTitle();
|
||||
|
||||
}, this));
|
||||
};
|
||||
|
||||
MailBoxUserScreen.prototype.onBuild = function ()
|
||||
|
|
|
@ -122,7 +122,7 @@
|
|||
|
||||
SettingsUserScreen.prototype.setSettingsTitle = function ()
|
||||
{
|
||||
require('App/User').setTitle(this.sSettingsTitle);
|
||||
require('App/User').setWindowTitle(this.sSettingsTitle);
|
||||
};
|
||||
|
||||
module.exports = SettingsUserScreen;
|
||||
|
|
5
dev/bootstrap.js
vendored
5
dev/bootstrap.js
vendored
|
@ -54,7 +54,7 @@
|
|||
|
||||
window['__APP_BOOT'] = function (fCall) {
|
||||
|
||||
$(function () {
|
||||
$(_.delay(function () {
|
||||
|
||||
if (!$('#rl-content').is(':visible'))
|
||||
{
|
||||
|
@ -82,7 +82,8 @@
|
|||
}
|
||||
|
||||
window['__APP_BOOT'] = null;
|
||||
});
|
||||
|
||||
}, 10));
|
||||
};
|
||||
|
||||
};
|
||||
|
|
|
@ -157,6 +157,7 @@ cfg.paths.js = {
|
|||
'vendors/queue/queue.min.js',
|
||||
'vendors/inputosaurus/inputosaurus.min.js',
|
||||
'vendors/moment/min/moment.min.js ',
|
||||
'vendors/tinycon/tinycon.min.js ',
|
||||
'vendors/routes/signals.min.js',
|
||||
'vendors/routes/hasher.min.js',
|
||||
'vendors/routes/crossroads.min.js',
|
||||
|
|
19
vendors/tinycon/LICENSE
vendored
Normal file
19
vendors/tinycon/LICENSE
vendored
Normal file
|
@ -0,0 +1,19 @@
|
|||
Copyright (c) 2013 Tom Moor
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
90
vendors/tinycon/README.md
vendored
Normal file
90
vendors/tinycon/README.md
vendored
Normal file
|
@ -0,0 +1,90 @@
|
|||
# Tinycon
|
||||
|
||||
A small library for manipulating the favicon, in particular adding alert bubbles and changing images. Tinycon gracefully falls back to a number in title approach for browers that don't support canvas or dynamic favicons.
|
||||
|
||||
<img src="https://github.com/tommoor/tinycon/blob/master/examples/screenshot.png?raw=true" />
|
||||
|
||||
<a href="http://tommoor.github.com/tinycon/">See the Live Demo here.</a>
|
||||
|
||||
## Documentation
|
||||
|
||||
Tinycon adds a single object to the global namespace and does not require initialisation.
|
||||
|
||||
### Basic Usage
|
||||
|
||||
```javascript
|
||||
Tinycon.setBubble(6);
|
||||
```
|
||||
|
||||
### Options
|
||||
|
||||
Tinycon can take a range of options to customise the look
|
||||
|
||||
* width: the width of the alert bubble
|
||||
* height: the height of the alert bubble
|
||||
* font: a css string to use for the fontface (recommended to leave this)
|
||||
* colour: the foreground font colour
|
||||
* background: the alert bubble background colour
|
||||
* fallback: should we fallback to a number in brackets for browsers that don't support canvas/dynamic favicons? Boolean, or use the string 'force' to ensure a title update even in supported browsers.
|
||||
* abbreviate: should tinycon shrink large numbers such as 1000 to an abbreviated version (1k). Boolean, defaults to true
|
||||
|
||||
```javascript
|
||||
Tinycon.setOptions({
|
||||
width: 7,
|
||||
height: 9,
|
||||
font: '10px arial',
|
||||
colour: '#ffffff',
|
||||
background: '#549A2F',
|
||||
fallback: true
|
||||
});
|
||||
```
|
||||
|
||||
### AMD support
|
||||
|
||||
Tinycon can also be used as an asynchronous module.
|
||||
|
||||
```javascript
|
||||
require([
|
||||
'tinycon.js'
|
||||
], function (T) {
|
||||
|
||||
T.setOptions({
|
||||
width: 7,
|
||||
height: 9,
|
||||
font: '10px arial',
|
||||
colour: '#ffffff',
|
||||
background: '#549A2F',
|
||||
fallback: true
|
||||
});
|
||||
|
||||
T.setBubble(7);
|
||||
|
||||
});
|
||||
```
|
||||
|
||||
## Browser Support
|
||||
|
||||
Tinycon has been tested to work completely in the following browsers. Older versions may be supported, but haven't been tested:
|
||||
|
||||
* Chrome 15+
|
||||
* Firefox 9+
|
||||
* Opera 11+
|
||||
|
||||
Currently the library degrades to title update:
|
||||
|
||||
* Internet Explorer 9
|
||||
* Safari 5
|
||||
|
||||
|
||||
## License / Credits
|
||||
|
||||
Tinycon is released under the MIT license. It is simple and easy to understand and places almost no restrictions on what you can do with Tinycon.
|
||||
[More Information](http://en.wikipedia.org/wiki/MIT_License)
|
||||
|
||||
Tinycon was inspired by [Notificon](https://github.com/makeable/Notificon)
|
||||
|
||||
|
||||
## Download
|
||||
|
||||
Releases are available for download from
|
||||
[GitHub](http://github.com/tommoor/tinycon/downloads).
|
279
vendors/tinycon/tinycon.js
vendored
Normal file
279
vendors/tinycon/tinycon.js
vendored
Normal file
|
@ -0,0 +1,279 @@
|
|||
/*!
|
||||
* Tinycon - A small library for manipulating the Favicon
|
||||
* Tom Moor, http://tommoor.com
|
||||
* Copyright (c) 2012 Tom Moor
|
||||
* @license MIT Licensed
|
||||
* @version 0.6.3
|
||||
*/
|
||||
|
||||
(function(){
|
||||
|
||||
var Tinycon = {};
|
||||
var currentFavicon = null;
|
||||
var originalFavicon = null;
|
||||
var faviconImage = null;
|
||||
var canvas = null;
|
||||
var options = {};
|
||||
var r = window.devicePixelRatio || 1;
|
||||
var size = 16 * r;
|
||||
var defaults = {
|
||||
width: 7,
|
||||
height: 9,
|
||||
font: 10 * r + 'px arial',
|
||||
colour: '#ffffff',
|
||||
background: '#F03D25',
|
||||
fallback: true,
|
||||
crossOrigin: true,
|
||||
abbreviate: true
|
||||
};
|
||||
|
||||
var ua = (function () {
|
||||
var agent = navigator.userAgent.toLowerCase();
|
||||
// New function has access to 'agent' via closure
|
||||
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')
|
||||
};
|
||||
|
||||
// private methods
|
||||
var getFaviconTag = function(){
|
||||
|
||||
var links = document.getElementsByTagName('link');
|
||||
|
||||
for(var i=0, len=links.length; i < len; i++) {
|
||||
if ((links[i].getAttribute('rel') || '').match(/\bicon\b/)) {
|
||||
return links[i];
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
var removeFaviconTag = function(){
|
||||
|
||||
var links = document.getElementsByTagName('link');
|
||||
var head = document.getElementsByTagName('head')[0];
|
||||
|
||||
for(var i=0, len=links.length; i < len; i++) {
|
||||
var exists = (typeof(links[i]) !== 'undefined');
|
||||
if (exists && (links[i].getAttribute('rel') || '').match(/\bicon\b/)) {
|
||||
head.removeChild(links[i]);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var getCurrentFavicon = function(){
|
||||
|
||||
if (!originalFavicon || !currentFavicon) {
|
||||
var tag = getFaviconTag();
|
||||
originalFavicon = currentFavicon = tag ? tag.getAttribute('href') : '/favicon.ico';
|
||||
}
|
||||
|
||||
return currentFavicon;
|
||||
};
|
||||
|
||||
var getCanvas = function (){
|
||||
|
||||
if (!canvas) {
|
||||
canvas = document.createElement("canvas");
|
||||
canvas.width = size;
|
||||
canvas.height = size;
|
||||
}
|
||||
|
||||
return canvas;
|
||||
};
|
||||
|
||||
var setFaviconTag = function(url){
|
||||
removeFaviconTag();
|
||||
|
||||
var link = document.createElement('link');
|
||||
link.type = 'image/x-icon';
|
||||
link.rel = 'icon';
|
||||
link.href = url;
|
||||
document.getElementsByTagName('head')[0].appendChild(link);
|
||||
};
|
||||
|
||||
var log = function(message){
|
||||
if (window.console) window.console.log(message);
|
||||
};
|
||||
|
||||
var drawFavicon = function(label, colour) {
|
||||
|
||||
// fallback to updating the browser title if unsupported
|
||||
if (!getCanvas().getContext || browser.ie || browser.safari || options.fallback === 'force') {
|
||||
return updateTitle(label);
|
||||
}
|
||||
|
||||
var context = getCanvas().getContext("2d");
|
||||
var colour = colour || '#000000';
|
||||
var src = getCurrentFavicon();
|
||||
|
||||
faviconImage = document.createElement('img');
|
||||
faviconImage.onload = function() {
|
||||
|
||||
// clear canvas
|
||||
context.clearRect(0, 0, size, size);
|
||||
|
||||
// draw the favicon
|
||||
context.drawImage(faviconImage, 0, 0, faviconImage.width, faviconImage.height, 0, 0, size, size);
|
||||
|
||||
// draw bubble over the top
|
||||
if ((label + '').length > 0) drawBubble(context, label, colour);
|
||||
|
||||
// refresh tag in page
|
||||
refreshFavicon();
|
||||
};
|
||||
|
||||
// allow cross origin resource requests if the image is not a data:uri
|
||||
// as detailed here: https://github.com/mrdoob/three.js/issues/1305
|
||||
if (!src.match(/^data/) && options.crossOrigin) {
|
||||
faviconImage.crossOrigin = 'anonymous';
|
||||
}
|
||||
|
||||
faviconImage.src = src;
|
||||
};
|
||||
|
||||
var updateTitle = function(label) {
|
||||
|
||||
if (options.fallback) {
|
||||
// Grab the current title that we can prefix with the label
|
||||
var originalTitle = document.title;
|
||||
|
||||
// Strip out the old label if there is one
|
||||
if (originalTitle[0] === '(') {
|
||||
originalTitle = originalTitle.slice(originalTitle.indexOf(' '));
|
||||
}
|
||||
|
||||
if ((label + '').length > 0) {
|
||||
document.title = '(' + label + ') ' + originalTitle;
|
||||
} else {
|
||||
document.title = originalTitle;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var drawBubble = function(context, label, colour) {
|
||||
|
||||
// automatic abbreviation for long (>2 digits) numbers
|
||||
if (typeof label == 'number' && label > 99 && options.abbreviate) {
|
||||
label = abbreviateNumber(label);
|
||||
}
|
||||
|
||||
// bubble needs to be larger for double digits
|
||||
var len = (label + '').length-1;
|
||||
|
||||
var width = options.width * r + (6 * r * len),
|
||||
height = options.height * r;
|
||||
|
||||
var top = size - height,
|
||||
left = size - width - r,
|
||||
bottom = 16 * r,
|
||||
right = 16 * r,
|
||||
radius = 2 * r;
|
||||
|
||||
// webkit seems to render fonts lighter than firefox
|
||||
context.font = (browser.webkit ? 'bold ' : '') + options.font;
|
||||
context.fillStyle = options.background;
|
||||
context.strokeStyle = options.background;
|
||||
context.lineWidth = r;
|
||||
|
||||
// bubble
|
||||
context.beginPath();
|
||||
context.moveTo(left + radius, top);
|
||||
context.quadraticCurveTo(left, top, left, top + radius);
|
||||
context.lineTo(left, bottom - radius);
|
||||
context.quadraticCurveTo(left, bottom, left + radius, bottom);
|
||||
context.lineTo(right - radius, bottom);
|
||||
context.quadraticCurveTo(right, bottom, right, bottom - radius);
|
||||
context.lineTo(right, top + radius);
|
||||
context.quadraticCurveTo(right, top, right - radius, top);
|
||||
context.closePath();
|
||||
context.fill();
|
||||
|
||||
// bottom shadow
|
||||
context.beginPath();
|
||||
context.strokeStyle = "rgba(0,0,0,0.3)";
|
||||
context.moveTo(left + radius / 2.0, bottom);
|
||||
context.lineTo(right - radius / 2.0, bottom);
|
||||
context.stroke();
|
||||
|
||||
// label
|
||||
context.fillStyle = options.colour;
|
||||
context.textAlign = "right";
|
||||
context.textBaseline = "top";
|
||||
|
||||
// unfortunately webkit/mozilla are a pixel different in text positioning
|
||||
context.fillText(label, r === 2 ? 29 : 15, browser.mozilla ? 7*r : 6*r);
|
||||
};
|
||||
|
||||
var refreshFavicon = function(){
|
||||
// check support
|
||||
if (!getCanvas().getContext) return;
|
||||
|
||||
setFaviconTag(getCanvas().toDataURL());
|
||||
};
|
||||
|
||||
var abbreviateNumber = function(label) {
|
||||
var metricPrefixes = [
|
||||
['G', 1000000000],
|
||||
['M', 1000000],
|
||||
['k', 1000]
|
||||
];
|
||||
|
||||
for(var i = 0; i < metricPrefixes.length; ++i) {
|
||||
if (label >= metricPrefixes[i][1]) {
|
||||
label = round(label / metricPrefixes[i][1]) + metricPrefixes[i][0];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return label;
|
||||
};
|
||||
|
||||
var round = function (value, precision) {
|
||||
var number = new Number(value);
|
||||
return number.toFixed(precision);
|
||||
};
|
||||
|
||||
// public methods
|
||||
Tinycon.setOptions = function(custom){
|
||||
options = {};
|
||||
|
||||
for(var key in defaults){
|
||||
options[key] = custom.hasOwnProperty(key) ? custom[key] : defaults[key];
|
||||
}
|
||||
return this;
|
||||
};
|
||||
|
||||
Tinycon.setImage = function(url){
|
||||
currentFavicon = url;
|
||||
refreshFavicon();
|
||||
return this;
|
||||
};
|
||||
|
||||
Tinycon.setBubble = function(label, colour) {
|
||||
label = label || '';
|
||||
drawFavicon(label, colour);
|
||||
return this;
|
||||
};
|
||||
|
||||
Tinycon.reset = function(){
|
||||
setFaviconTag(originalFavicon);
|
||||
};
|
||||
|
||||
Tinycon.setOptions(defaults);
|
||||
window.Tinycon = Tinycon;
|
||||
|
||||
if(typeof define === 'function' && define.amd) {
|
||||
define(Tinycon);
|
||||
}
|
||||
|
||||
})();
|
8
vendors/tinycon/tinycon.min.js
vendored
Normal file
8
vendors/tinycon/tinycon.min.js
vendored
Normal file
|
@ -0,0 +1,8 @@
|
|||
/*!
|
||||
Tinycon - A small library for manipulating the Favicon
|
||||
Tom Moor, http://tommoor.com
|
||||
Copyright (c) 2012 Tom Moor
|
||||
@license MIT Licensed
|
||||
@version 0.6.3
|
||||
*/
|
||||
(function(){var Tinycon={};var currentFavicon=null;var originalFavicon=null;var faviconImage=null;var canvas=null;var options={};var r=window.devicePixelRatio||1;var size=16*r;var defaults={width:7,height:9,font:10*r+'px arial',colour:'#ffffff',background:'#F03D25',fallback:true,crossOrigin:true,abbreviate:true};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')};var getFaviconTag=function(){var links=document.getElementsByTagName('link');for(var i=0,len=links.length;i<len;i++){if((links[i].getAttribute('rel')||'').match(/\bicon\b/)){return links[i]}}return false};var removeFaviconTag=function(){var links=document.getElementsByTagName('link');var head=document.getElementsByTagName('head')[0];for(var i=0,len=links.length;i<len;i++){var exists=(typeof(links[i])!=='undefined');if(exists&&(links[i].getAttribute('rel')||'').match(/\bicon\b/)){head.removeChild(links[i])}}};var getCurrentFavicon=function(){if(!originalFavicon||!currentFavicon){var tag=getFaviconTag();originalFavicon=currentFavicon=tag?tag.getAttribute('href'):'/favicon.ico'}return currentFavicon};var getCanvas=function(){if(!canvas){canvas=document.createElement("canvas");canvas.width=size;canvas.height=size}return canvas};var setFaviconTag=function(url){removeFaviconTag();var link=document.createElement('link');link.type='image/x-icon';link.rel='icon';link.href=url;document.getElementsByTagName('head')[0].appendChild(link)};var log=function(message){if(window.console)window.console.log(message)};var drawFavicon=function(label,colour){if(!getCanvas().getContext||browser.ie||browser.safari||options.fallback==='force'){return updateTitle(label)}var context=getCanvas().getContext("2d");var colour=colour||'#000000';var src=getCurrentFavicon();faviconImage=document.createElement('img');faviconImage.onload=function(){context.clearRect(0,0,size,size);context.drawImage(faviconImage,0,0,faviconImage.width,faviconImage.height,0,0,size,size);if((label+'').length>0)drawBubble(context,label,colour);refreshFavicon()};if(!src.match(/^data/)&&options.crossOrigin){faviconImage.crossOrigin='anonymous'}faviconImage.src=src};var updateTitle=function(label){if(options.fallback){var originalTitle=document.title;if(originalTitle[0]==='('){originalTitle=originalTitle.slice(originalTitle.indexOf(' '))}if((label+'').length>0){document.title='('+label+') '+originalTitle}else{document.title=originalTitle}}};var drawBubble=function(context,label,colour){if(typeof label=='number'&&label>99&&options.abbreviate){label=abbreviateNumber(label)}var len=(label+'').length-1;var width=options.width*r+(6*r*len),height=options.height*r;var top=size-height,left=size-width-r,bottom=16*r,right=16*r,radius=2*r;context.font=(browser.webkit?'bold ':'')+options.font;context.fillStyle=options.background;context.strokeStyle=options.background;context.lineWidth=r;context.beginPath();context.moveTo(left+radius,top);context.quadraticCurveTo(left,top,left,top+radius);context.lineTo(left,bottom-radius);context.quadraticCurveTo(left,bottom,left+radius,bottom);context.lineTo(right-radius,bottom);context.quadraticCurveTo(right,bottom,right,bottom-radius);context.lineTo(right,top+radius);context.quadraticCurveTo(right,top,right-radius,top);context.closePath();context.fill();context.beginPath();context.strokeStyle="rgba(0,0,0,0.3)";context.moveTo(left+radius/2.0,bottom);context.lineTo(right-radius/2.0,bottom);context.stroke();context.fillStyle=options.colour;context.textAlign="right";context.textBaseline="top";context.fillText(label,r===2?29:15,browser.mozilla?7*r:6*r)};var refreshFavicon=function(){if(!getCanvas().getContext)return;setFaviconTag(getCanvas().toDataURL())};var abbreviateNumber=function(label){var metricPrefixes=[['G',1000000000],['M',1000000],['k',1000]];for(var i=0;i<metricPrefixes.length;++i){if(label>=metricPrefixes[i][1]){label=round(label/metricPrefixes[i][1])+metricPrefixes[i][0];break}}return label};var round=function(value,precision){var number=new Number(value);return number.toFixed(precision)};Tinycon.setOptions=function(custom){options={};for(var key in defaults){options[key]=custom.hasOwnProperty(key)?custom[key]:defaults[key]}return this};Tinycon.setImage=function(url){currentFavicon=url;refreshFavicon();return this};Tinycon.setBubble=function(label,colour){label=label||'';drawFavicon(label,colour);return this};Tinycon.reset=function(){setFaviconTag(originalFavicon)};Tinycon.setOptions(defaults);window.Tinycon=Tinycon;if(typeof define==='function'&&define.amd){define(Tinycon)}})();
|
|
@ -38,6 +38,7 @@ module.exports = {
|
|||
'hasher': 'window.hasher',
|
||||
'Jua': 'window.Jua',
|
||||
'Autolinker': 'window.Autolinker',
|
||||
'Tinycon': 'window.Tinycon',
|
||||
'buzz': 'window.buzz',
|
||||
'ssm': 'window.ssm',
|
||||
'key': 'window.key',
|
||||
|
|
Loading…
Reference in a new issue