Carles Andrés

Passionate Web Developer

QuickTip: Change a Favicon Programatically

Sometimes it’s very useful to manipulate a favicon dynamically from your javascript. It turns out it might be easier than you thought.

A very simple favicon formed by a filled-in circle superimposed with a letter can be achieved in 3 simple steps:

  1. Create the image using the canvas API
  2. Convert the canvas image to a dataURL
  3. Replace the page’s favicon with newly created image (by removing the previous and adding the new one)

The following code achieves exactly that purpose.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 var replaceFavicon = function(src){
     document.head || (document.head = document.getElementsByTagName('head')[0]);
     var link = document.createElement('link');
     var oldLink = document.getElementById('dynamic-favicon');
     link.id = 'dynamic-favicon';
     link.rel = 'shortcut icon';
     link.href = src;
     if (oldLink) {
        document.head.removeChild(oldLink);
     }
     document.head.appendChild(link);
}

 var createFavicon = function(color, letter){
    color = color || 'black';
    letter = letter || 't';
    var ctx;
    var strData;

    // These 100px is an arbitrary size, good enough for changing the small
    // icon in a browser's tab which is usually far smaller
    var canvas = document.createElement('canvas');
    canvas.setAttribute('width', 100);
    canvas.setAttribute('height', 100);


    ctx = canvas.getContext('2d');
    ctx.arc( 50,50,50,0,2*Math.PI );
    ctx.fillStyle = color;
    ctx.fill();

    // Draw letter
    ctx.fillStyle = 'white';
    ctx.font = 'bold normal 90px monospace';
    ctx.fillText(letter, 25, 75);

    strData = canvas.toDataURL('image/png', 1.0);
    replaceFavicon(strData);
};


 createFavicon('#ddd');

You can see this code in action at https://carlesandres.github.io/change_favicon/ .

And you can make contributions to the code in https://github.com/carlesandres/change_favicon .

My web application Textmarkr.com makes use of that same code to help identify the currently open file among all other browser tabs using the same app.

Your comments are more than welcome. :)

Some Grunt Tasks for JS Libraries

While recently working on the development of a Javascript library, I had the goal of automating the release process as much as possible. The main tasks that I wanted to automate were:

  • Adding a copyright banner at the top of our compiled JS library files
  • Tagging our git repo with our library version
  • Deploying our library to an AWS bucket

The team was already using Grunt to automate the build process through a custom grunt build task, so we were ready to build our grunt release task on top of it.

Creating a Grunt Task for Easier Testing

As an avid Yeoman user I start many of my pet projects, and some of my professional ones, by invoking generator-webapp. However, I miss the powerful development tools provided by the browser when I find a bug in my tests while running them through PhantomJS.

Therefore, after running yo webapp, one of the first things that I usually do is to add a custom task to my Gruntfile so that I can run my tests in a browser window.

Debugging Rails Routes Issues

Yesterday I had to debug a very silly error in Rails while developing a feature for Typo. The error message was:

Unknown action
The action 'merge' could not be found for Admin::ContentController

Of course, I was pretty sure I had done everything right but, I couldn’t just ignore it.

At first, I thought it might be an error in my routing configuration, although this was not what the error message said (Stupid me). However, I wanted to make sure there was no subtle routing problem I wasn’t aware of.

First, I used Chrome Developer Tools to inspect the Http request and everything I found seemed ok.

Then I did some research so as to further inspect the call to the failing action’s route. I discovered I could open a rails console from within my app folder:

Installing phpDocumentor in XAMPP on Windows

When I tried installing phpDocumentor alongside XAMPP on my Windows Machine, I found it somewhat tricky. Thus, I decided to post my installation steps here for future reference.

Create a pear subfolder inside your document root folder(e.g. c:\xampp\htdocs\pear).

In a DOS window, go to:

1
c:\xampp\php

Execute the following .:

1
pear config-set data_dir c:/xampp/htdocs/pear

(substitute c:/xampp/htdocs with your document root)

You should get the message:

1
config-set succeded

And then type:

1
pear install PhpDocumentor

That’s it! PhpDocumentor installation should being and, if everyting worked OK, you should be able to access PhpDocumentor’s web interface through: http://localhost/pear/PhpDocumentor

However if you get an error message like this one (which I got):

1
"Warning: include_once(c: mpp\htdocs\pear/PhpDocumentor/docbuilder/includes/utilities.php) [function.include-once]: failed to open stream: Invalid argument in C:\xampp\htdocs\pear\PhpDocumentor\docbuilder\config.php on line 53"

Then you must go into the PhpDocumentor/docbuilder/ folder in the location you installed PhpDocumentor at, open these files: config.php, actions.php, builder.php and edit this line in each of them.

1
include_once("c:\xampp\htdocs\pear/PhpDocumentor/docbuilder/includes/utilities.php" );

And change c:\ to c:\\

I took this fix from this nexua. So all credit is deserved to them.