update tinycon to latest (#4850)

This commit is contained in:
Anil Mandepudi
2016-07-14 10:59:31 -07:00
committed by Julian Lam
parent 3858e9c614
commit 1d100e9f42

View File

@@ -1,188 +1,200 @@
/*! /*!
* Tinycon - A small library for manipulating the Favicon * Tinycon - A small library for manipulating the Favicon
* Tom Moor, http://tommoor.com * Tom Moor, http://tommoor.com
* Copyright (c) 2012 Tom Moor * Copyright (c) 2015 Tom Moor
* MIT Licensed * @license MIT Licensed
* @version 0.6.1 * @version 0.6.4
*/ */
(function(){ (function(){
var Tinycon = {}; var Tinycon = {};
var currentFavicon = null; var currentFavicon = null;
var originalFavicon = null; var originalFavicon = null;
var originalTitle = document.title; var faviconImage = null;
var faviconImage = null; var canvas = null;
var canvas = null; var options = {};
var options = {}; var r = window.devicePixelRatio || 1;
var r = window.devicePixelRatio || 1; var size = 16 * r;
var size = 16 * r; var defaults = {
var defaults = { width: 7,
width: 7, height: 9,
height: 9, font: 10 * r + 'px arial',
font: 9 * r + 'px arial', color: '#ffffff',
colour: '#ffffff', background: '#F03D25',
background: '#F03D25', fallback: true,
fallback: true, crossOrigin: true,
crossOrigin: true, abbreviate: true
abbreviate: true };
};
var ua = (function () { var ua = (function () {
var agent = navigator.userAgent.toLowerCase(); var agent = navigator.userAgent.toLowerCase();
// New function has access to 'agent' via closure // New function has access to 'agent' via closure
return function (browser) { return function (browser) {
return agent.indexOf(browser) !== -1; return agent.indexOf(browser) !== -1;
}; };
}()); }());
var browser = { var browser = {
ie: ua('msie'), ie: ua('trident'),
chrome: ua('chrome'), chrome: ua('chrome'),
webkit: ua('chrome') || ua('safari'), webkit: ua('chrome') || ua('safari'),
safari: ua('safari') && !ua('chrome'), safari: ua('safari') && !ua('chrome'),
mozilla: ua('mozilla') && !ua('chrome') && !ua('safari') mozilla: ua('mozilla') && !ua('chrome') && !ua('safari')
}; };
// private methods // private methods
var getFaviconTag = function(){ var getFaviconTag = function(){
var links = document.getElementsByTagName('link'); var links = document.getElementsByTagName('link');
for(var i=0, len=links.length; i < len; i++) { for(var i=0, len=links.length; i < len; i++) {
if ((links[i].getAttribute('rel') || '').match(/\bicon\b/)) { if ((links[i].getAttribute('rel') || '').match(/\bicon\b/i)) {
return links[i]; return links[i];
} }
} }
return false; return false;
}; };
var removeFaviconTag = function(){ var removeFaviconTag = function(){
var links = document.getElementsByTagName('link'); var links = document.getElementsByTagName('link');
var head = document.getElementsByTagName('head')[0]; var head = document.getElementsByTagName('head')[0];
for(var i=0, len=links.length; i < len; i++) { for(var i=0, len=links.length; i < len; i++) {
var exists = (typeof(links[i]) !== 'undefined'); var exists = (typeof(links[i]) !== 'undefined');
if (exists && (links[i].getAttribute('rel') || '').match(/\bicon\b/)) { if (exists && (links[i].getAttribute('rel') || '').match(/\bicon\b/i)) {
head.removeChild(links[i]); head.removeChild(links[i]);
} }
} }
}; };
var getCurrentFavicon = function(){ var getCurrentFavicon = function(){
if (!originalFavicon || !currentFavicon) { if (!originalFavicon || !currentFavicon) {
var tag = getFaviconTag(); var tag = getFaviconTag();
originalFavicon = currentFavicon = tag ? tag.getAttribute('href') : '/favicon.ico'; currentFavicon = tag ? tag.getAttribute('href') : '/favicon.ico';
} if (!originalFavicon) {
originalFavicon = currentFavicon;
}
}
return currentFavicon; return currentFavicon;
}; };
var getCanvas = function (){ var getCanvas = function (){
if (!canvas) { if (!canvas) {
canvas = document.createElement("canvas"); canvas = document.createElement("canvas");
canvas.width = size; canvas.width = size;
canvas.height = size; canvas.height = size;
} }
return canvas; return canvas;
}; };
var setFaviconTag = function(url){ var setFaviconTag = function(url){
removeFaviconTag(); if(url){
removeFaviconTag();
var link = document.createElement('link'); var link = document.createElement('link');
link.type = 'image/x-icon'; link.type = 'image/x-icon';
link.rel = 'icon'; link.rel = 'icon';
link.href = url; link.href = url;
document.getElementsByTagName('head')[0].appendChild(link); document.getElementsByTagName('head')[0].appendChild(link);
}; }
};
var log = function(message){ var log = function(message){
if (window.console) window.console.log(message); if (window.console) window.console.log(message);
}; };
var drawFavicon = function(label, colour) { var drawFavicon = function(label, color) {
// fallback to updating the browser title if unsupported // fallback to updating the browser title if unsupported
if (!getCanvas().getContext || browser.ie || browser.safari || options.fallback === 'force') { if (!getCanvas().getContext || browser.ie || browser.safari || options.fallback === 'force') {
return updateTitle(label); return updateTitle(label);
} }
var context = getCanvas().getContext("2d"); var context = getCanvas().getContext("2d");
var colour = colour || '#000000'; var color = color || '#000000';
var src = getCurrentFavicon(); var src = getCurrentFavicon();
faviconImage = document.createElement('img'); faviconImage = document.createElement('img');
faviconImage.onload = function() { faviconImage.onload = function() {
// clear canvas // clear canvas
context.clearRect(0, 0, size, size); context.clearRect(0, 0, size, size);
// draw the favicon // draw the favicon
context.drawImage(faviconImage, 0, 0, faviconImage.width, faviconImage.height, 0, 0, size, size); context.drawImage(faviconImage, 0, 0, faviconImage.width, faviconImage.height, 0, 0, size, size);
// draw bubble over the top // draw bubble over the top
if ((label + '').length > 0) drawBubble(context, label, colour); if ((label + '').length > 0) drawBubble(context, label, color);
// refresh tag in page // refresh tag in page
refreshFavicon(); refreshFavicon();
}; };
// allow cross origin resource requests if the image is not a data:uri // allow cross origin resource requests if the image is not a data:uri
// as detailed here: https://github.com/mrdoob/three.js/issues/1305 // as detailed here: https://github.com/mrdoob/three.js/issues/1305
if (!src.match(/^data/) && options.crossOrigin) { if (!src.match(/^data/) && options.crossOrigin) {
faviconImage.crossOrigin = 'anonymous'; faviconImage.crossOrigin = 'anonymous';
} }
faviconImage.src = src; faviconImage.src = src;
}; };
var updateTitle = function(label) { var updateTitle = function(label) {
if (options.fallback) { if (options.fallback) {
if ((label + '').length > 0) { // Grab the current title that we can prefix with the label
document.title = '(' + label + ') ' + originalTitle; var originalTitle = document.title;
} else {
document.title = originalTitle;
}
}
};
var drawBubble = function(context, label, colour) { // Strip out the old label if there is one
if (originalTitle[0] === '(') {
originalTitle = originalTitle.slice(originalTitle.indexOf(' '));
}
// automatic abbreviation for long (>2 digits) numbers if ((label + '').length > 0) {
if (typeof label == 'number' && label > 99 && options.abbreviate) { document.title = '(' + label + ') ' + originalTitle;
label = abbreviateNumber(label); } else {
} document.title = originalTitle;
}
}
};
// bubble needs to be larger for double digits var drawBubble = function(context, label, color) {
var len = (label + '').length-1;
var width = options.width * r + (6 * r * len), // automatic abbreviation for long (>2 digits) numbers
height = options.height * r; if (typeof label == 'number' && label > 99 && options.abbreviate) {
label = abbreviateNumber(label);
}
var top = size - height, // 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, left = size - width - r,
bottom = 16 * r, bottom = 16 * r,
right = 16 * r, right = 16 * r,
radius = 2 * r; radius = 2 * r;
// webkit seems to render fonts lighter than firefox // webkit seems to render fonts lighter than firefox
context.font = (browser.webkit ? 'bold ' : '') + options.font; context.font = (browser.webkit ? 'bold ' : '') + options.font;
context.fillStyle = options.background; context.fillStyle = options.background;
context.strokeStyle = options.background; context.strokeStyle = options.background;
context.lineWidth = r; context.lineWidth = r;
// bubble // bubble
context.beginPath(); context.beginPath();
context.moveTo(left + radius, top); context.moveTo(left + radius, top);
context.quadraticCurveTo(left, top, left, top + radius); context.quadraticCurveTo(left, top, left, top + radius);
context.lineTo(left, bottom - radius); context.lineTo(left, bottom - radius);
context.quadraticCurveTo(left, bottom, left + radius, bottom); context.quadraticCurveTo(left, bottom, left + radius, bottom);
context.lineTo(right - radius, bottom); context.lineTo(right - radius, bottom);
context.quadraticCurveTo(right, bottom, right, bottom - radius); context.quadraticCurveTo(right, bottom, right, bottom - radius);
@@ -191,77 +203,85 @@
context.closePath(); context.closePath();
context.fill(); context.fill();
// bottom shadow // bottom shadow
context.beginPath(); context.beginPath();
context.strokeStyle = "rgba(0,0,0,0.3)"; context.strokeStyle = "rgba(0,0,0,0.3)";
context.moveTo(left + radius / 2.0, bottom); context.moveTo(left + radius / 2.0, bottom);
context.lineTo(right - radius / 2.0, bottom); context.lineTo(right - radius / 2.0, bottom);
context.stroke(); context.stroke();
// label // label
context.fillStyle = options.colour; context.fillStyle = options.color;
context.textAlign = "right"; context.textAlign = "right";
context.textBaseline = "top"; context.textBaseline = "top";
// unfortunately webkit/mozilla are a pixel different in text positioning // unfortunately webkit/mozilla are a pixel different in text positioning
context.fillText(label, r === 2 ? 29 : 15, browser.mozilla ? 7*r : 6*r); context.fillText(label, r === 2 ? 29 : 15, browser.mozilla ? 7*r : 6*r);
}; };
var refreshFavicon = function(){ var refreshFavicon = function(){
// check support // check support
if (!getCanvas().getContext) return; if (!getCanvas().getContext) return;
setFaviconTag(getCanvas().toDataURL()); setFaviconTag(getCanvas().toDataURL());
}; };
var abbreviateNumber = function(label) { var abbreviateNumber = function(label) {
var metricPrefixes = [ var metricPrefixes = [
['G', 1000000000], ['G', 1000000000],
['M', 1000000], ['M', 1000000],
['k', 1000] ['k', 1000]
]; ];
for(var i = 0; i < metricPrefixes.length; ++i) { for(var i = 0; i < metricPrefixes.length; ++i) {
if (label >= metricPrefixes[i][1]) { if (label >= metricPrefixes[i][1]) {
label = round(label / metricPrefixes[i][1]) + metricPrefixes[i][0]; label = round(label / metricPrefixes[i][1]) + metricPrefixes[i][0];
break; break;
} }
} }
return label; return label;
}; };
var round = function (value, precision) { var round = function (value, precision) {
var number = new Number(value); var number = new Number(value);
return number.toFixed(precision); return number.toFixed(precision);
}; };
// public methods // public methods
Tinycon.setOptions = function(custom){ Tinycon.setOptions = function(custom){
options = {}; options = {};
for(var key in defaults){ // account for deprecated UK English spelling
options[key] = custom.hasOwnProperty(key) ? custom[key] : defaults[key]; if (custom.colour) {
} custom.color = custom.colour;
return this; }
};
Tinycon.setImage = function(url){ for(var key in defaults){
currentFavicon = url; options[key] = custom.hasOwnProperty(key) ? custom[key] : defaults[key];
refreshFavicon(); }
return this; return this;
}; };
Tinycon.setBubble = function(label, colour) { Tinycon.setImage = function(url){
label = label || ''; currentFavicon = url;
drawFavicon(label, colour); refreshFavicon();
return this; return this;
}; };
Tinycon.reset = function(){ Tinycon.setBubble = function(label, color) {
setFaviconTag(originalFavicon); label = label || '';
}; drawFavicon(label, color);
return this;
};
Tinycon.setOptions(defaults); Tinycon.reset = function(){
window.Tinycon = Tinycon; currentFavicon = originalFavicon;
})(); setFaviconTag(originalFavicon);
};
Tinycon.setOptions(defaults);
window.Tinycon = Tinycon;
})();