Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Add jQuery.Tinycon as a jQuery plugin for base library #29

Closed
wants to merge 1 commit into from

3 participants

@albburtsev

The size of minified script less:
jquery.tinycon.min.js - 2125
tinycon.min.js - 3869

@tommoor
Owner

Hey, Tinycon was specifically coded not to contain any dependencies, i'm not sure what the advantage of wrapping it as a jquery plugin would be?

@ssokolow

I agree. Normally, having an optional jQuery wrapper can be useful so you can include a plugin in a chain of method calls for simplicity and clean code... but that generally assumes you're operating on something you had to retrieve via a selector.

Given that Tinycon is essentially a singleton operating on a global value (the page title), I don't see any benefit to even an optional jQuery plugin.

@tommoor
Owner

Thanks for the effort here, but as there isn't a clear advantage to this i'm going to close the issue.

@tommoor tommoor closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on May 10, 2012
  1. @albburtsev
This page is out of date. Refresh to see the latest.
Showing with 246 additions and 0 deletions.
  1. +22 −0 examples/jquery.html
  2. +211 −0 jquery.tinycon.js
  3. +13 −0 jquery.tinycon.min.js
View
22 examples/jquery.html
@@ -0,0 +1,22 @@
+<html>
+ <head>
+ <link rel="icon" href="favicon.ico">
+ <title>jQuery.Tinycon</title>
+
+ <script src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
+ <script src="../jquery.tinycon.js"></script>
+ <script>
+ (function(){
+ var count = 0;
+ setInterval(function(){
+
+ if (++count > 99) count = 0;
+ Tinycon.setBubble(count);
+
+ }, 1000);
+ })();
+ </script>
+ </head>
+ <body>
+ </body>
+</html>
View
211 jquery.tinycon.js
@@ -0,0 +1,211 @@
+/**
+ * @description jQuery.Tinycon - Tinycon library as a jQuery plugin
+ * @requires jQuery >= 1.0
+ * @author Tom Moor, http://tommoor.com
+ * @author Alexander Burtsev - author of a jQuery plugin
+ * @license MIT
+ * @version 0.2.6
+ */
+
+(function($, window, document) {
+ 'use strict';
+
+ var Tinycon = {},
+ currentFavicon = null,
+ originalFavicon = null,
+ originalTitle = document.title,
+ faviconImage = null,
+ canvas = null,
+ options = {},
+ defaults = {
+ width: 7,
+ height: 9,
+ font: '10px arial',
+ colour: '#ffffff',
+ background: '#F03D25',
+ fallback: true
+ };
+
+ // private methods
+ function getFaviconTag() {
+ var _link = null;
+
+ $('link').each(function() {
+ var _this = $(this);
+ if ( (_this.attr('rel') || '').match(/\bicon\b/) )
+ return _link = _this, false;
+ });
+
+ return _link;
+ };
+
+ function removeFaviconTag() {
+ $('link').each(function() {
+ var _this = $(this);
+ if ( (_this.attr('rel') || '').match(/\bicon\b/) ) // in original was ```getAttribute('rel') === 'icon'```, why?
+ _this.remove();
+ });
+ };
+
+ function getCurrentFavicon() {
+ if ( !originalFavicon || !currentFavicon ) {
+ var icon = getFaviconTag();
+ originalFavicon = currentFavicon = icon ? icon.attr('href') : '/favicon.ico';
+ }
+
+ return currentFavicon;
+ };
+
+ function getCanvas() {
+ if ( !canvas )
+ canvas = $('<canvas>').attr({
+ width: 16,
+ height: 16
+ });
+
+ return canvas.get(0);
+ };
+
+ function setFaviconTag(url) {
+ removeFaviconTag();
+
+ $('<link>')
+ .attr({
+ type: 'image/x-icon',
+ rel: 'icon',
+ href: url
+ })
+ .appendTo('head');
+ };
+
+ function log(message) {
+ if ( window.console )
+ console.log(message);
+ };
+
+ function drawFavicon(num, colour) {
+ // fallback to updating the browser title if unsupported
+ if ( !getCanvas().getContext || options.fallback === 'force')
+ return updateTitle(num);
+
+ var context = getCanvas().getContext('2d'),
+ colour = colour || '#000000',
+ num = num || 0,
+ src = getCurrentFavicon();
+
+ faviconImage = new Image();
+ faviconImage.onload = function() {
+
+ // clear canvas
+ context.clearRect(0, 0, 16, 16);
+
+ // draw original favicon
+ context.drawImage(faviconImage, 0, 0, faviconImage.width, faviconImage.height, 0, 0, 16, 16);
+
+ // draw bubble over the top
+ if ( num > 0 )
+ drawBubble(context, num, 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/) )
+ faviconImage.crossOrigin = 'anonymous';
+
+ faviconImage.src = src;
+ };
+
+ function updateTitle(num) {
+ if ( !options.fallback )
+ return;
+
+ if ( num > 0 )
+ document.title = '('+num+') ' + originalTitle;
+ else
+ document.title = originalTitle;
+ };
+
+ function drawBubble(context, num, colour) {
+ // bubble needs to be larger for double digits
+ var len = num.toString().length - 1,
+ width = options.width + (6 * len),
+ w = 16 - width,
+ h = 16 - options.height;
+
+ // 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 = 1;
+
+ // bubble
+ context.fillRect(w,h,width-1,options.height);
+
+ // rounded left
+ context.beginPath();
+ context.moveTo(w-0.5,h+1);
+ context.lineTo(w-0.5,15);
+ context.stroke();
+
+ // rounded right
+ context.beginPath();
+ context.moveTo(15.5,h+1);
+ context.lineTo(15.5,15);
+ context.stroke();
+
+ // bottom shadow
+ context.beginPath();
+ context.strokeStyle = 'rgba(0,0,0,0.3)';
+ context.moveTo(w,16);
+ context.lineTo(15,16);
+ context.stroke();
+
+ // number
+ context.fillStyle = options.colour;
+ context.textAlign = 'right';
+ context.textBaseline = 'top';
+
+ // unfortunately webkit/mozilla are a pixel different in text positioning
+ context.fillText(num, 15, $.browser.mozilla ? 7 : 6);
+ };
+
+ function refreshFavicon() {
+ // check support
+ if ( !getCanvas().getContext )
+ return;
+
+ setFaviconTag(getCanvas().toDataURL());
+ };
+
+ // public methods
+ $.extend(Tinycon, {
+ setOptions: function(custom) {
+ options = $.extend({}, defaults, custom);
+ return Tinycon;
+ },
+ setImage: function(url) {
+ currentFavicon = url;
+ refreshFavicon();
+ return Tinycon;
+ },
+ setBubble: function(num, colour) {
+ // validate
+ if( isNaN(parseFloat(num)) || !isFinite(num) )
+ return log('Bubble must be a number');
+
+ drawFavicon(num, colour);
+ return Tinycon;
+ },
+ reset: function() {
+ this.setImage(originalFavicon);
+ return Tinycon;
+ }
+ });
+
+ Tinycon.setOptions(defaults);
+ $.Tinycon = window.Tinycon = Tinycon;
+
+})(jQuery, window, document);
View
13 jquery.tinycon.min.js
@@ -0,0 +1,13 @@
+/**
+ * @description jQuery.Tinycon - Tinycon library as a jQuery plugin
+ * @requires jQuery >= 1.0
+ * @author Tom Moor, http://tommoor.com
+ * @author Alexander Burtsev - author of a jQuery plugin
+ * @license MIT
+ * @version 0.2.6
+ */
+
+(function(e,k,l){function p(){var a=null;e("link").each(function(){var d=e(this);if((d.attr("rel")||"").match(/\bicon\b/))return a=d,!1});return a}function q(){e("link").each(function(){var a=e(this);(a.attr("rel")||"").match(/\bicon\b/)&&a.remove()})}function r(){if(!g||!h){var a=p();g=h=a?a.attr("href"):"/favicon.ico"}return h}function f(){j||(j=e("<canvas>").attr({width:16,height:16}));return j.get(0)}function s(a){if(!f().getContext||"force"===d.fallback){var c;d.fallback?l.title=0<a?"("+a+") "+
+m:m:c=void 0;return c}var b=f().getContext("2d"),a=a||0;c=r();i=new Image;i.onload=function(){b.clearRect(0,0,16,16);b.drawImage(i,0,0,i.width,i.height,0,0,16,16);if(0<a){var c=a,h=d.width+6*(c.toString().length-1),f=16-h,g=16-d.height;b.font=(e.browser.webkit?"bold ":"")+d.font;b.fillStyle=d.background;b.strokeStyle=d.background;b.lineWidth=1;b.fillRect(f,g,h-1,d.height);b.beginPath();b.moveTo(f-0.5,g+1);b.lineTo(f-0.5,15);b.stroke();b.beginPath();b.moveTo(15.5,g+1);b.lineTo(15.5,15);b.stroke();
+b.beginPath();b.strokeStyle="rgba(0,0,0,0.3)";b.moveTo(f,16);b.lineTo(15,16);b.stroke();b.fillStyle=d.colour;b.textAlign="right";b.textBaseline="top";b.fillText(c,15,e.browser.mozilla?7:6)}n()};c.match(/^data/)||(i.crossOrigin="anonymous");i.src=c}function n(){if(f().getContext){var a=f().toDataURL();q();e("<link>").attr({type:"image/x-icon",rel:"icon",href:a}).appendTo("head")}}var c={},h=null,g=null,m=l.title,i=null,j=null,d={},o={width:7,height:9,font:"10px arial",colour:"#ffffff",background:"#F03D25",
+fallback:!0};e.extend(c,{setOptions:function(a){d=e.extend({},o,a);return c},setImage:function(a){h=a;n();return c},setBubble:function(a,d){if(isNaN(parseFloat(a))||!isFinite(a))k.console&&console.log("Bubble must be a number");else return s(a,d),c},reset:function(){this.setImage(g);return c}});c.setOptions(o);e.Tinycon=k.Tinycon=c})(jQuery,window,document);
Something went wrong with that request. Please try again.