Full Screen Image Viewer

There is a site that I like to visit when I’m just looking for something fun or interesting. The site is in spanish, but that doesn’t matter because most of the time there are videos, many of them in English, and other languages. There are also images, so the fact that the site is in Spanish should not matter even if you don’t speak or understand Spanish. The site is http://malgusto.com/ and one of the sections that I enjoy a lot is the Fotografias HD section (http://www.malgusto.com/fotografias-hd/). However, I always thought it was such a shame that the images cannot be made into full screen mode for a better experience.

I decided to write my own script on Firefox’s scratchpad. Here is the simple script that I wrote:


var imgs = document.querySelectorAll('div.caja_imagenes img,marcosimple');
var dummyImg = document.createElement('img');
dummyImg.style.height = 0;
document.body.appendChild(dummyImg);
var currentIndx = 0;
var totalImgs = imgs.length;

document.addEventListener('keyup', function(e) {
    if (e.keyCode == 39) {
        if (currentIndx == totalImgs -1) {
            currentIndx = -1;
        }
        currentIndx ++;
        dummyImg.src = imgs[currentIndx].src;
    }
    if (e.keyCode == 37) {
        if (currentIndx == 0) {
            currentIndx = totalImgs;
        }
        currentIndx --;
        dummyImg.src = imgs[currentIndx].src;
    }
});

for(img in imgs) {
    if (!imgs[img].addEventListener) {
        continue;
    }
    imgs[img].idx = img;
    imgs[img].addEventListener('click', function(e) {
        currentIndx = this.idx;
        dummyImg.src = this.src;
        dummyImg.mozRequestFullScreen();
    },
    false);
}

It may or may not be the best way to do it, but it works, and in this case that is all that matters.

Here is the script made into a bookmarklet so you can save it and use it later. NOTE: Follow the bookmarklet link. WordPress would not allow me to add the javascript bookmarklet here, so I had to host it elsewhere.

How to use:

First, drag the bookmarklet link to your bookmarks bar to save it.
Then you can open one of the posts in the Fotografias HD section. For example, http://www.malgusto.com/fotografias-hd/recopilacion-de-imagenes-hd-98/#more-59444
Then, click on the bookmarklet once the page has loaded.
Now you can click any of the HD images, and it will take you to full screen mode. Use the arrows on the keyboard to navigate through the images.

Please enojoy the bookmarklet and have fun!

Becareful with isNaN and Type Conversion

As you may know, Javascript is a loosely typed language. It knows about data types, but it just doesn’t care too much about them. This can be both, a good and a bad thing. For this reason, you must always be careful when dealing with different data types, especially because they can be converted from one type to another automatically, which can lead to unexpected results and nasty bugs.

Today I came across such a situation. I was building a form that needs to update itself based on some values, such as number of tickets, and extra donations. When I was checking if there where any extra donation, I was first making sure that the donation value was a number, and not some other value. For that I did this:


if (isNaN(extra)) {
  extra = 0;
}

As you can see, we assume that if the value is not a number, it must be 0, meaning no donation is made. This seems like a good working code, but it is not. It has a few flaws that make it buggy.

Before continuing, you should know that the extra value is used later to calculate the total of the transaction. For that I have a line like this:

grand_total = ticket_price + extra

What happens if the user inputs 3 on the donation field, and the ticket is 100. You would expect the grand total to be 103, but it is not. It is actually 1003. This is because the 3 is a string type, not a number. There are a few ways to convert the 3 from a string to a number, one of them is using parseInt. So, lets add that to the code:


if (isNaN(extra)) {
  extra = 0;
}
extra = parseInt(extra, 10);

Now, we get the right result (103, not 1003). But remember that I told you that the code was buggy? Well, imagine now, that instead of entering a 3, the user leaves the donation field blank. What would happen? Well, grand total will now be NaN...

Why? Because when you do this:

if (isNaN(''))

The empty string is evaluated to false, which evaluates to 0, which has been converted to a number type, which of course is a number. So, now your code inside the if statement is not executed, and extra remains an empty string. But, when you pass an empty string to parseInt it returns NaN, because of course an empty string is not a number, and in this case there is no data conversion to make that empty string into a nice 0. Later when you want to add the ticket price to the extra donation, you are actually trying to add 100 to NaN, which will give you NaN as a result.

In other words, according to isNaN an empty string is a number, but according to parseInt an empty string is not a number, and this is thanks to type conversion.

The solution is quite simple, test the value return by parseInt to see if it is a number:

if (isNaN(parseInt(extra)))

This kind of bugs are easy to miss, and they can result in really bad situations. This is one of the reasons why type conversion is not so cool sometimes.

Let Us Fail Silently

Or Screw the Programmer, We Are Google

It’s been too long since I last worked with the google maps API. Today I was working with it again, and I got a bit lost because some things have changed since I last worked with it. Not so much as the api, but the set up for working with it. Google now has an API console, and it was a bit new for me. But that was not a problem. Google always makes it hard to get started, but easy the get used to.

My complain today has to do with the way they fail to let you know what went wrong. I spent 30 minutes trying to find out what was wrong with my code only to realize that I had misspelled the word zoom in the options passed to the maps constructor function.

The fix was quick once I discovered the error, just spell the word right! But I can’t help to feel like something could have been done to save me those 30 minutes. First of all, why does it even fail? And why does it do it silently?

Well, apparently maps needs to know the zoom at which you want it to be displayed. This means, that if no zoom is specified, the map will simply not show. But why not let the programmer know? They do display an ugly alert if you use a non-valid api key, why not in other cases as well?

To be fair, the problem could have been caught earlier, but since I hadn’t worked maps for a while, my initial assumption was that something had changed, and that I didn’t know about it. Maybe I had to call some method of the Map object in order for it to display. Or maybe it was something else.

I paid close attention to the values of the options defined, but not to the option names. I guess you could say I should have, but then again, I could argue that there should be meaningful debug messages in the API. And what about default options?

As developers we ought to make sure we implement meaningful debug messages to out libraries and apis. It is useful for us, and for other who use our code. When something is required, and not provided, your api/library should complain about it. Throw a freaking error/exception or at least log an error to the console, or even do an f-ing alert, but don’t just fail silently without any indication of what went wrong.

add_role, the Wrong Way

While working on a project that I think will be useful to many freelancers, I came across a little problem. After about an hour of debugging, I found the reason, and I thought it would be good to document it here for posterity.

Before you continue reading, please be aware that this is a “stupid” mistake kind of thing, but that lead me to know more about wordpress, and the way it works.

The Problem

The problem I run into was that the current_user_can function of wordpress’ was returning false when I knew the user had the capability I was asking for, since I was logged in as a user that has such capability. Why was I getting false?

A Bit of Context

Let me give you some context to the problem so you can follow better. I am building, against my own good judgement, and another developers, a wordpress based project management system for freelancers and small teams. One developer told me I may be trying to stretch the boundaries of wordpress far too much, but I am a stubborn person, and yes, even I think it is not such a good idea to build it wordpress based, but my hope is that I can cling on to the popularity that wordpress has to make the system successful and popular.

The system works based on user types, that are nothing more than wordpress roles. As you may know, a wordpress role is just a way of specifying different types of users, and roles have predefined capabilities.

In order to add a new role, you just need to call the add_role function, passing the role name, screen name, and capabilities. The capabilities is nothing but an array listing the capabilities of the role.

As you now know, my problem was that even though the user had a capability, it was being reported as not having it.

The Source of the Bug and the Solution

As it turns out, the source of the bug was a stupid mistake on my end. When you call add_role and pass the capabilities list, you are supposed to pass it as an associative array:


$caps = array(
'somecap'=>true,
'someother'=>true
);

But I just passed a regular array in. This caused the problem.

The solution is simply to re-generate the roles passing in an associative array.

Pretty simple, yet it took me about an hour to realize where my mistake was. If you want to know what I learned in the process, read on.

The Lesson Learned

The first thing I learned was that current_user_can simply runs the has_cap method of the current user’s, which in turn, among other things, returns true if all the capabilities specified are within the list of capabilities that the user has.

All the capabilities that the user has are set in a property of the user object called allcaps, and the way wordpress checks if a user has a certain capability is by passing that capability as an index of the allcaps property to see if it is empty or not. If it is empty, then the user does not have such capability, and the has_cap method returns false.

This is the relevant code, taken from wordpress 3.5.1
wp-include/capabilities.php line 939

if ( empty( $capabilities[ $cap ] ) )
  return fasle

Notice that here allcaps has been passed through a filter and the returning value saved in $capabilities.

With that knowledge, I decided to look at the content of all caps, which revealed the problem:


//Not the actual output, but similar
Aray(
  [0]=>'cap',
  [1]=>'anothercap',
  [user_role]=>1
  [exist]=>1
);

As you can see, cap, and anothercap are both set as the values of index 0, and 1 respectively, not as the indexes like user_role, and exist are. This was a problem since wordpress was looking for $capabilities['cap'], and didn’t find it. But why is it that they are not being set as indexes, but rather as values?

In order to find out, I had to do a bit more of code digging.

The Mysterious allcaps

All I knew by now was that the problem was the capabilities not being set as indexes of the capabilities list, but rather as values of numerical indexes, which made it impossible for wordpress to find them in the list of capabilities. However, I did not know why. Upon inspecting the admin user and the user with the custom role, I noticed that the capabilities of the admin user where being set correctly, that is, as indexes, not as values. I decided to check how the allcaps array was being set.

The allcaps attribute of the user object is set by the get_role_caps method defined on line 734 of the capabilities file on wordpress 3.5.1, but there isn’t really much going on there. The function simply merges the capabilities of the role, and the ones of the user, but further investigation of the difference between the capabilities of the role of the admin user, and those of the user with the custom role, revealed that they were different. The ones of the admin were being set correctly, that is, as indexes, but the ones of the custom role were not. Why was that?

In order to know why that was happening, I decided to investigate how the capabilities of each role was set.

The user object has a property called roles, which lists the roles of a user, but only as a string identifying the role. If you want to get the actual role, you need to call the get_role method of the wp_roles object. The wp_roles object is an instance of the WP_Roles class defined in the same file. The get_role method returns an instance of the WP_Role class, which among other properties has a property called capabilities, which lists all the capabilities of the role, and which was being set wrong in my custom role.

Define the Role Object’s Capabilities Property

If you look at the source of the WP_Role class, you will see that the capabilities are passed to it on instantiation. This means that inspecting the WP_Role class won’t help us that much. Instead we need to find where the roles are instantiated to see how the capabilities that are passed to them are constructed.

Instantiating WP_Role

Luckily by now we know that the roles are returned by the get_role method of the wp_roles object. This means that we should start there if we want to know how they are instantiated, and eventually find out how the capabilities array is being constructed, and why it is not being constructed right in this case.


Line 244 of the capabilities file in wordpress 3.5.1
marks the beginning of the get_role method. This method doesn’t do much. It simply returns the role object if it has it, or null if it doesn’t. The role objects are stored in the role_objects property of the wp_roles object. This property is set when the object is created. If you look at the _init method of the wp_roles object, you will see that the roles are obtained by getting and option from the database. This option is simply a serialized array containing all the role definitions and their capabilities. After unserializing the array, I noticed that all the default roles had their capabilities defined as indexes of the capabilities array, with their values set to true (actually to 1, but the serialized array marks that 1 as a boolean value) whereas my custom roles had their capabilities defined as values of numerical indexes in the capabilities array. That is when I realized I must have had done something wrong when I created my custom roles.

I decided to check the docs for the add_role function, and I noticed the proper way of defining roles, and their capabilities.

As you can see, I made a small, and stupid mistake when I created my custom roles, but it led me to a better comprehension of the platform that I am using. So, I encourage you to learn from your mistakes so that you can become a better programmer every day.

Assorted Links

http://www.enlightenment.org/p.php?p=about/terminology&l=en

http://motherboard.vice.com/blog/solar-powered-trash-cans-saved-philadelphia-almost-a-million-bucks

https://simonsfoundation.org/features/science-news/biologists-home-in-on-turing-patterns/

http://www.rdegges.com/the-positive-programmer/

http://www.theregister.co.uk/2013/03/28/i_accidentally_the_internet/

http://javascriptweblog.wordpress.com/2011/08/08/fixing-the-javascript-typeof-operator/

http://javascriptweblog.wordpress.com/2011/05/31/a-fresh-look-at-javascript-mixins/

http://javascriptweblog.wordpress.com/2011/05/03/javascript-strict-mode/

http://javascriptweblog.wordpress.com/2011/04/04/the-javascript-comma-operator/

http://dustindiaz.com/qwery

http://dustindiaz.com/regex-brain-teaser-part-ii

http://www.adequatelygood.com/Replacing-setTimeout-Globally.html

http://www.adequatelygood.com/Writing-Testable-JavaScript.html

http://www.adequatelygood.com/Minimum-Timer-Intervals-in-JavaScript.html

http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html

http://alt1040.com/2013/03/reforma-de-telecomunicaciones-en-mexico-de-que-se-trata-en-que-nos-afecta

http://alt1040.com/2013/03/fosa-de-las-marianas-microbios

http://davidwalsh.name/remove-html-comments-php

Links of the Day

Some may be repeated from previous posts. I have been reviewing old reads lately.

http://scie.nti.st/2008/8/22/gnu-screen-with-vertical-split-support/

http://lugatgt.org/content/gnu_screen/downloads/presentation.pdf

https://en.wikipedia.org/wiki/Dovecot_%28software%29

http://www.computerhope.com/ushort.htm

http://www.oreillynet.com/linux/cmd/cmd.csp?path=s/screen

http://fishbowl.pastiche.org/2004/01/19/persistent_login_cookie_best_practice/

http://developer.yahoo.com/blogs/ydn/posts/2007/01/douglas_crockford_advanced_jav/

http://courses.cms.caltech.edu/cs11/misc/xwindows.html

http://www.objectmentor.com/resources/articles/Principles_and_Patterns.pdf

http://html5doctor.com/how-to-get-html5-working-in-ie-and-firefox-2/

http://zaemis.blogspot.com/2009/06/currying-in-php.html

http://www.kuro5hin.org/story/2004/3/9/16838/14935

http://lifehacker.com/307609/reduce-terminal-clutter-with-gnu-screen

http://web.archive.org/web/20040613170158/http://ashitaka-san.home.comcast.net/yayrant/antiswitch.html

http://tomayko.com/writings/Screen (Not very interesting, or useful, but just for the record…)

http://extralogical.net/articles/currying-javascript.html

http://danwebb.net/2006/11/3/from-the-archives-cleaner-callbacks-with-partial-application

https://grouptalent.com/blog/why-we-don-t-use-heroku

http://calnewport.com/blog/2011/11/11/if-youre-busy-youre-doing-something-wrong-the-surprisingly-relaxed-lives-of-elite-achievers/

http://www.goodboydigital.com/pixi-js-is-out/

http://vinay.howtolivewiki.com/blog/other/why-theres-no-money-the-imaginary-part-of-financial-systems-3235

http://thoughtcatalog.com/2013/procrastination-is-not-laziness/

What Is Currying Useful For?

Have you ever heard of currying? Currying is basically taking a function that takes 2 or more arguments and turning it into one that returns a function that can be called with a single argument. The returned function then returns yet another function which also can be called with a single argument. This continues for as many times as the number of arguments in the original functions. In other words, instead of doing this:


sum(1, 2, 3);

You do this:


sum(1)(2)(3);

But, why would you want to do that? At first sight it does not seem very useful. However, it is.

Imagine you have a function that takes two arguments. The first argument would be a DOM node reference, and the second would be a string. The function takes the string, and sets it as the text content of the element referenced as the first argument. In Javascript the function would be something like this:


function writeToNode(node, value) {
  node.innerHTML = value;
}

The curried version of that function would be something like this:


function writeToNode(node) {
  return function (value) {
    node.innerHTML = value;
  }
}

As you can see writeToNode now returns a function that takes the value as the argument. This function is the one to perform the task. What is the benefit of that? Well, it all actually depends on what you are doing, but think of for example a situation where you want to be able to show a different message depending on some condition:


var nodeRef = writeToNode(node);

if (condition) {
  nodeRef('Condition is true');
} else {
  nodeRef('Condition is false);
}

This example is pretty simple, so the benefit may be not even noticeable, but in a more complex situation they are obvious.

Why would you want to change your code to be like that anyway? Why not just do this:


// Here the function is not curried.
if (condition) {
  nodeRef(node, 'Condition is true');
} else {
  nodeRef(node, 'Condition is false);
}

Well that works well in this example (if you ignore the fact that you are repeating your self there anyway), but what happens when instead of passing a node reference you want to pass an id? The non-curried function becomes this:


function writeToNode(id, value) {
  var node = document.getElementById('id');
  node.innerHTML = value;
}

If you are used to optimizing your code, then I’m sure you already spotted the problem with the function. Every time you call that function, there is DOM interaction, which you should reduce as much as possible. Sure you could use a closure to save a reference to the DOM node, but that brings in its own problems:


var writeToNode = (function() {
  var node;
  return function (id, value) {
    if (!node) {
      node = document.getElementById(id);
    }
    node.innerHTML = value;
  }
}());

By doing this, you’ve accomplished a few things. You’ve made it so that the function only interacts with the DOM once, but you’ve also made it so that the node can never be changed. There are ways to overcome that but they make the function even more complex. Since we are talking about complexity, you have also made the function more complex than it needs to be.

There are many other benefits of currying, but at the end it all comes down to a single simple principle: Always use the best tool for the job. Sure currying has benefits over the example shown here, but there are instances where currying will not be the way to go. So, always look for the best way to accomplish the task at hand.