Tinycon

A small library for manipulating the Favicon

Este script no debería instalarse directamente. Es una biblioteca que utilizan otros scripts mediante la meta-directiva de inclusión // @require https://update.greasyfork.org/scripts/36273/236489/Tinycon.js

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

/*!
 * 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;
  }

})();