A small library for manipulating the Favicon
Dieses Skript sollte nicht direkt installiert werden. Es handelt sich hier um eine Bibliothek für andere Skripte, welche über folgenden Befehl in den Metadaten eines Skriptes eingebunden wird // @require https://update.greasyfork.org/scripts/36273/236489/Tinycon.js
/*!
* Tinycon - A small library for manipulating the Favicon
* Tom Moor, http://tommoor.com
* Copyright (c) 2015 Tom Moor
* @license MIT Licensed
+ @special modifed for lorify-ng extension by OpenA
*/
(function(){
var Tinycon = {};
var currentFavicon = null;
var originalFavicon = null;
var faviconImage = null;
var canvas = null;
var options = {};
// Chrome browsers with nonstandard zoom report fractional devicePixelRatio.
var r = Math.ceil(window.devicePixelRatio) || 1;
var size = 16 * r;
var options = {
width: 7,
height: 9,
font: 10 * r + 'px arial',
color: '#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('trident'),
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/i)) {
return links[i];
}
}
return false;
};
var removeFaviconTag = function(){
var links = document.getElementsByTagName('link');
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/i)) {
links[i].parentNode.removeChild(links[i]);
}
}
};
var getCurrentFavicon = function(){
if (!originalFavicon || !currentFavicon) {
var tag = getFaviconTag();
currentFavicon = tag ? tag.getAttribute('href') : '/favicon.ico';
if (!originalFavicon) {
originalFavicon = currentFavicon;
}
}
return currentFavicon;
};
var getCanvas = function (){
if (!canvas) {
canvas = document.createElement("canvas");
canvas.width = size;
canvas.height = size;
}
return canvas;
};
var setFaviconTag = function(url){
if(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, color) {
// 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 color = color || '#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, color);
// 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, color) {
// automatic abbreviation for long (>2 digits) numbers
if (typeof label == 'number' && label > 99 && options.abbreviate) {
label = abbreviateNumber(label);
}
var radius = canvas.width / 100 * 38,
centerX = canvas.width - radius,
centerY = radius,
fontPix = radius * 1.5;
// webkit seems to render fonts lighter than firefox
context.font = 'bold '+ fontPix +'px arial';
context.fillStyle = '#48de3d';
context.strokeStyle = 'rgba(0,0,0,0.2)';
// bubble
context.beginPath();
context.arc(centerX, centerY, radius, 0, 2 * Math.PI, false);
context.fill();
context.stroke();
// label
context.fillStyle = '#fff';
context.textAlign = "center";
context.fillText(label, centerX, fontPix);
};
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);
};
Tinycon.setImage = function(url){
currentFavicon = url;
refreshFavicon();
return this;
};
Tinycon.setBubble = function(label, color) {
label = label || '';
drawFavicon(label, color);
return this;
};
Tinycon.reset = function(){
currentFavicon = originalFavicon;
setFaviconTag(originalFavicon);
};
if(typeof define === 'function' && define.amd) {
define(Tinycon);
} else if (typeof module !== 'undefined') {
module.exports = Tinycon;
} else {
window.Tinycon = Tinycon;
}
})();