Read “JavaScript : The Good Parts”

A nice and short book. The author, Douglas Crockford, is a man who really understand why and how JavaScript was designed and evolved. So the book feels like an interesting tale told by a grandpa.

JavaScript is a language, also a system. Like every complex system, it has bad parts. The basic idea of this book is: we can turn JavaScript to a better language by “avoid using its bad parts”. This probably also applies to most systems. Actually smart people do this naturally, as long as they realize which part is good and which is bad. When bad features of a system are realized by more people (just realized, probably not understood, since bad parts are usually difficult to understand), more ppl will get around them or even invent replacement features. In this way bad features died out gradually. That’s why we can see different features in a system covering the same thing.

Another important point in this book is to keep codes human-readable. It’s easy to write machine-understandable codes, but costs much more efforts to make it easy to understand and transfer among humans. Lots of “bad parts” listed by this book are simply because they “mess codes up” more than the benefits they were designed for. An additional point is the most dangerous features are those who bring in hard-to-find bugs, not those notorious features that everyone will pay attention to.

This book is pretty short, but as the author says, it worths reading time to time.

How to Draw Dashed Lines in Canvas

(I could finally finish this draft, after 4 months -_-)

I’m a fun of JavaScript Canvas but I couldn’t believe it doesn’t support drawing dashed lines when this requirement occurs to me. After some investigating I found a good summary about why/how it doesn’t support dashed lines.

What I actually do with canvas is to draw data chart, with a cool JS library named Flot. The reason I need dashed lines is that someone (chuckle) is color-blind so he couldn’t tell the colored lines apart.

One day I decided to have a look at how Flash handles this. To my surprise, Flash doesn’t support dashed lines “natively”, either. So maybe Canvas doesn’t support that for the same reason? However, flash uses an elegant “external” way to draw dashed lines, here is the explanation/demo/code snippet about it.

The ActionScript codes for drawing dashed lines are not hard to understand, so I ported them to JS, or rather, to Flot. Demo. However it isn’t perfect, firstly it’s too slow on IE7 (maybe because of excanvas is not efficient enough?), secondly I didn’t find a good way to draw proper legends for Flot. See Issue 61 of Flot for detail and implementation in patch file.

At least, we can draw dashed lines in Canvas, in the same way as in Flash. Just the performance of IE7 sucks….

Make StatCounter More Readable

我比较爱看这个blog访问的StatCounter统计数据。昨天还比较了一下Google AnalyticsGoStats和StatCounter这几家的统计服务,个人还是觉得StatCounter最好用。Google Analytics界面好难用,GoStats免费用户限制太多。还听说过的比较有名的一个好像叫做MINT。其实这几个都算是比较好的了。昨天还看到了某人主页上用的不知哪家的统计服务,还会弹广告窗口的,lol

不过每次看的时候还是有点问题。我最经常看的是Pageloads的统计,这里可以看到哪个页面被访问了,还有这个访问的refer地址,也就是这次访问的上一个页面。常见的refer地址是搜索引擎,或者一些带有俺的blog地址的页面,比如WordPress网站上我写的那个小plugin的页面。一条记录显示出来大概是这样

StatCounter original pageload list

这条记录上第一行是访问者的ip和域名,第二行是访问的页面的标题,第三行是这次访问的refer地址。比较不爽的一点就是标题和refer地址里面有很多编码之后的中文,我常常还要点一下去看看人家是用什么关键字来查的。研究了一下之后发现标题里面那种%u9AD8这样的编码,后面这四位就是Unicode Number;google搜索的url里面带有的%D0%A1这种是用utf-8编码的,这两个都比较容易用JavaScript来转换。Baidu这个家伙的URL里面看起来和google挺像,也是%CB%C9这样的,但其实用的是GB2312编码,要转换到utf-8需要查很大的表,不是单纯用JavaScript就可以做的了。Whatever,能把标题和google搜索的utf8编码转换过来也就方便不少了。

基本的想法就是在页面读取完之后执行一段JS,这个就需要用到Firefox的插件GreaseMonkey。我按照GreaseMonkey的规范写了一小段User JavaScript,还挺好用,嘿嘿。每次看StatCounter的pageload页面的时候这段小程序就会自动工作,转换以后的效果是这样

StatCounter pageload list after using my script

代码在这里下载——StatReadable.user.js
有用的部分是这几句

allLinks = document.evaluate(
"//td[@class='tableContent1Left']/a[@target='_blank']|
//td[@class='tableContent2Left']/a[@target='_blank']",
document,null,XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE,null);
for (var i = 0; i < allLinks.snapshotLength; i++) {
    thisLink = allLinks.snapshotItem(i);
    // do something with thisLink
    oldHTML = thisLink.innerHTML;
    //for %uXXXX
    newHTML = oldHTML.replace(
        /%u([0-9A-Z][0-9A-Z][0-9A-Z][0-9A-Z])/g,"�$1;");
    Try.these(
        function (){
            //for utf8 encoding
            newHTML = newHTML.replace(/((%[A-Z0-9][A-Z0-9])+)/g,
                function(str,p1,offset,flags){
                    return decodeURIComponent(p1);
                }
            );
        }
    );
    thisLink.innerHTML = newHTML;
}

其实Baidu那个也可以使用比较猥琐的方法搞定,先把页面的Encoding手动设成GB2312,然后把鼠标移到baidu那个url上面,浏览器下面的状态栏里面显示的就是汉字了。。可以用Firefox的Content Preference这个插件来锁定StatCounter的编码到GB。