Showing newest 39 of 62 posts from September 2010. Show older posts
Showing newest 39 of 62 posts from September 2010. Show older posts

Detroit 1-8-7

It's an old-style police drama about homicide detectives. Nothing fancy about technology, no impressive huge projector (could somebody turn on the light?), no vast computer monitor (it would take you 3.1415926 seconds to walk from end to end of that monitor), no incredible multi-touch screen (ain't your hands tired?), no Windows-7-like gradient or translucency filter (my eyes hurt), no RSA-encrytion break (give me a break really), no tap-in into analogous CCTV (how on Earth they could do that, psychic?), just simple and straight into the point of a show like this should be.



I was wondering recently, why would so many police drama shows have to make up a lot of sci-fi equipment/interface stuff? It's not as if you can't have hi-tech stuff, but they really over-do and ridiculous exaggerate.

The first one I saw which has been under control is Chase. It has a great start, especially the first fight scene. I noticed the actress also played in Past Life, which I only watched the first episode. The bad guy was from The Beast, good show, but he looked more like bad guy in The Beast. Anyway, after starting, it became average.

Then Hawaii Five-0, a re-imagining version, its pace was too fast for pilot episode, I felt they rushed to put everything into place in just one episode. I don't know if that's what the original does, but it just don't make sense to me. In the end of first episode, they were cleaning up the office, where the heck those documents from? Those were like records or reports after ten years work. The leading actor, you should know he is the doctor from Three Rivers, cancelled, it had a lot of fancy stuff and the characters settings were really strange, but I watched whole season.

Back to Detroit 1-8-7, since it goes back the most important element of a show, it all depends on how the actors act. I think they are good. The only flaw in my opinion is the thing that Det. Finch has for Det. Sanchez, that really ruined the first episode. Why would writers always put love affection in every show?

Is it true that you can find many different caliber casings on a bridge in Detroit?

WebP read time

Google just announced a new image format, WebP. The statistics of compression ratio looks very promising. But I wonder about the process time of reading. So I downloaded webp-leptonica (version 0.0.1) tarball and added few lines to webpconv.c to time it with libvpx 0.9.0 (with mmx sse sse2 ssse3 threads flags).

--- webpconv.c.original 2010-09-30 02:19:39.000000000 +0800
+++ webpconv.c  2010-10-01 08:26:48.000000000 +0800
@@ -39,6 +39,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <time.h>
 #include "allheaders.h"

 #define DEFAULT_PSNR 42.0
@@ -218,13 +219,17 @@
     }

     struct Pix \*pixs;
+    clock_t c0, c1;
+    c0 = clock();
     if (!strcmp(ext, ".webp")) {
       pixs = pixReadWebP(argv[a_idx]);
     } else {
       pixs = pixRead(argv[a_idx]);
     }
+    c1 = clock();
+    printf ("Elapsed CPU time on reading pixels: %10.6f seconds\n", (float) (c1 - c0) / CLOCKS_PER_SEC);
     FREE(ext);
-
+    
     if (pixs == NULL) {
       fprintf(stderr, "Failed to read image\n");
       return 1;
@@ -240,6 +245,7 @@
       format = "png";
     }

+    c0 = clock();
     if (strcmp(format, "bmp") == 0) {
       pixWrite(fileout, pixs, IFF_BMP);
     } else if (strcmp(format, "jpeg") == 0) {
@@ -275,6 +281,8 @@
     else {
       return ERROR_INT("Format not supported", "webpconv", 1);
     }
+    c1 = clock();
+    printf ("Elapsed CPU time on conversion    : %10.6f seconds\n", (float) (c1 - c0) / CLOCKS_PER_SEC);

     free(fileout);
     pixDestroy(&pixs);

My goal is to time pixRead() and pixReadWebP(). This may just be a rough numbers, here is the results on images from this page:

The blue block is about JPG to WebP, and the purple block is about WebP, which is from previous conversion of JPG to WebP, to WebP. I didn't set the quality, I let the program to decide on its own.

As you can see the size are reduced after the conversion. But, interestingly, the read time or decode time, it's not the same story. For bigger images, it seems to need more time for decoding pixel data. I don't know about image library or processing. Maybe this is not practical or the library is not optimized yet. Anyway, this new format is still new.

Honestly, I don't really think anyone can kill JPEG, even the Google. Yes, Google may be able to push this new format or anything into our programs, WebM is the good example. But the old stuff support is too hard to be dropped, till today some people still use GIF (not for animation) instead of PNG. If someday, Flickr supports the WebP embedding, I will still not use it to put images in my blog.

By the way, why are 5.jpg and 8.jpg missing?

Graphing processes using Graphviz

Graphing processes using Graphviz

Just thought I could make one like this. You can use pstree to get a text-version in tree style.

Here are the codes:
cat /proc/*/status | awk '
BEGIN {printf("graph G {\n")}
/Name/ {name = $2}
/^Pid/ {pid = $2}
/PPid/ {
  if (PROCINFO["ppid"] != $2) {
    printf("p%d [label = \"%s\"]\n", pid, name);
    if ($2 != 0)
      printf("p%d -- p%d\n", pid, $2);
    }
  }
END {printf("}")}' | circo -T png -o test.png

It outputs all process except the current processes (cat/awk/circo). You can use if ('$$' != $2) { to replace the checking code, $$ is the current Bash shell's process ID, which is awk's parent process ID. Note that part is actually being processed in Bash not awk. The awk code pauses before $$, then continues after.

Next one hide the kernel threads:
cat /proc/*/status | awk '
BEGIN {printf("graph G {\n")}
/Name/ {name = $2}
/^Pid/ {pid = $2}
/PPid/ {
  if ($2 == 2 || pid == 2) {
    printf("p%d [label = \"%s\"]\n", pid, name);
    if ($2 != 0)
      printf("p%d -- p%d\n", pid, $2);
    }
  }
END {printf("}")}' | circo -T png -o test.png

I am not sure if all kernel threads are with PID #2, but it works for me. And if those children had children, then this code will work probably.

The last one only show kernel threads:
cat /proc/*/status | awk '
BEGIN {printf("graph G {\n")}
/Name/ {name = $2}
/^Pid/ {pid = $2}
/PPid/ {
  if ($2 != 2 && pid != 2 && PROCINFO["ppid"] != $2) {
    printf("p%d [label = \"%s\"]\n", pid, name);
    if ($2 != 0)
      printf("p%d -- p%d\n", pid, $2);
    }
  }
END {printf("}")}' | circo -T png -o test.png

When September ends

... there will be some shows end their seasons or take a short break and some others start or resume.

Ben dies (I guess) in Covert Affairs, Henry continues Unnatural History, Myka quits her job in Warehouse 13, and Mozzie assassinated in White Collar. I love these four, hope none of them got cancelled.

But Supernatural is back

Supernatural
(sidenote: I just knew Google owns Picnik (bought this March) via this post)

, as well as Chuck, NCIS, NCIS: LA, Stargate: Universe, and The Big Bang Theory. CSI and its spin-offs have come back but I don't watch them anymore.

There are more new shows, what a busy season would be!

Didn't know I were a Japanese

I was checking if comments were imported correctly on Disqus, I checked one of my post and saw this reaction:


The translation by Google Translate (probably only 50% correct):
Japanese strong man to write the script /2010/05/bash-oauth.html + library. However, over the wall still has to ... ... RT @ beyondwdq: @ dickeny this ye do? Even before direct user name password authentication is, now I can not

I am not complaining or anything, just wondering why this Twitter thought I was a Japanese. I don't know Japanese, therefore I couldn't have any posts written in Japanese. In fact, I have never talked about Japan or Japanese in this blog. My name is written in Chinese Pinyin, definitely don't read like a Japanese name.

I am a Taiwanese if you want to know.

No Ordinary Family

I think this definitely is a good comedy show for me in 2010-2011. An accident gives the Powells family each a new power.



Sounds like a family version of Fantastic Four (the role father was actually in this film) but in a more diverse way. They are not all like Super Man powers. Only the parents, the children's powers are different, inwards. Or like The Incredibles, but their powers are born naturally.

I thought they would be fighting crimes, but it seems like a uncertainty since the bad guy with super power showed up at the end of pilot, probably the father would do. If they do, I wonder if they would get some special dress? Hope not.

I wonder what powers those bad guys have. Can't wait for episode two.

Cute little orange button

Can't recall when was last time I took a shot of him.

IMG_2548

IMG_2547

The look on his face (or any cat's) is always thoughtful, though he may not be really thinking.

I wish I could have taken a photo like this. But never got a chance, running away when he gets flashed, there was always not having enough light to take a shot without flash. This cat hates flash light, but who ever likes?

Migrate Blogger to Blogger

The title is not totally correct, it's sort of like merge one blog into another one. I have many blogs beside this one you are reading, but they are no longer updated. I have been thinking for a long time whether if I should move those posts here and delete the old blog. If I delete the old blog, some websites which link to my posts will be failed to let visitors get what they come for. Finally, I concluded one acceptable resolution. I can still redirect visitors to new place thought it won't be a 301 redirection, just a notice on old page. It's okay for me.

Here is steps I have taken to move posts of five blogs into this one:

  • Resynchronize remaining comments on Disqus with Blogger
  • Export old blog and import on new blog
  • Apply special label
  • Add special label check in template for showing notice, so reader would know they are from old blog
  • Publish those imported posts
  • Import existing Blogger comments into Disqus
  • Update old blog's template to show redirection notice
  • Redirect old blog's feed to new blog's feed
  • Transfer old blog to another Google account

Notices

One thing important is to let visitors know a post has been moved and a post is imported from another blog. The reason to let visitor knows a post is imported is because the post might be messed up due to difference of template.

The first notice, you can see an example here: http://fedoratux.blogspot.com/2009/11/migrating-to-tmux-from-gnuscreen.html.

I almost emptied the Blogger layout template to show just that. I was hoping I could direct print out the new link without JavaScript, but it's not possible unless there is some unveiled Blogger expr function which I don't know. Here is the template you can use:

<!DOCTYPE html>
<html>
<head>
  <title><data:blog.pageTitle/> has been moved!</title>
  <meta http-equiv="Content-Type" expr:content='"text/html; charset=" + data:blog.encoding'/>
<b:skin/>
<style>
* {
  font-family: Arial;
}
#notice {
  background-color: pink;
  border: 3px solid pink;
  border-radius: 3px;
  box-shadow: 0 0 3px pink;
  color: #fff;
  font-size: 2em;
  font-weight: bold;
  padding: 1ex;
  text-shadow: 0 0 3px #000;
}
#new_url {
  color: red;
  font-family: monospace;
}
</style>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'/>
<!--[if lt IE 9]>
<script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<script>
$(function () {
var new_homepageUrl = '/';
var new_url = '<data:blog.url/>'.replace('<data:blog.homepageUrl/>', new_homepageUrl);
$('#new_url')
  .css('color', '#fff')
  .attr('href', new_url)
  .text(new_url);
});
</script>
</head>
<body>

<h1 id='title'><data:blog.pageTitle/></h1>

<div id='notice'>
This page has been moved to <a id='new_url' href='#'>(Please enable JavaScript to see the new link)</a>.
</div>

</body>
</html>

Don't forget to change new_homepageUrl variable if you are going to use.

The second notice is on new place, you can see an example here: /2009/11/migrating-to-tmux-from-gnuscreen.html. (Just below the post date)

I have something like the following code just below post date in layout template:

<b:if cond='data:post.labels'><b:loop values='data:post.labels' var='label'>
<b:if cond='data:label.name == &quot;SPECIAL LABEL&quot;'>
<div class='old-post-notice'>This post was imported from my old blog &amp;ldquo;BLOG NAME&amp;rdquo; on 2010-09-28. Some stuff in this post may be broken, please leave a comment if you see any, then I will try to fix it.</div>
</b:if>
</b:loop></b:if>

Notice that SPECIAL LABEL? You will need to apply a special label for those imported posts. I have OldBlogTuxWearsFedora for one blog's posts.

Feed redirection and blog transfer

I set up feed redirection in old blog with new blog's feed. I think it's for readers who couldn't notice any changes. After you set up the redirection, post a notice post in new blog to draw old blog's readers' attention, notify them to update feed link.

As for blog transfer, I created new account and move those blogs into that new account along with some other blogs which I don't think I shouldn't merge them but I don't want to see them in my dashboard anymore.

Conclusion

There is one thing if you wonder—which was my question—what about the difference of timezones of two blogs? That may cause date changes but not for permalink, once you firstly post a post, then permalink is fixed and will never be changed.

I don't like duplicates, some people may import and keep contents of old blog, not me. My method is only to touch template, the content is actually still on old blog untouched. You can see them as backup or archive.

Now, I only have five blogs in my dashboard, used to have 14. The list in FeedBurner is shorter, I am going to delete those Google Analytics profiles. I don't think I would ever want to read old statistics. I think I can't transfer few profiles of one account, therefore I only can delete them.

One more thing is about the comments. If you use Blogger comment system, there should have no problem for you. I use Disqus, I think those comments should be able to be imported, but Disqus currently seems having problem doing import. I hope that won't cause duplicates but I will have to find out later.

Updated on 2010-09-29

Disqus has imported the comments and it didn't make duplicates, I think. Here is the result

Import Details

Status:    Import completed
Threads:   502
Comments:  118 (110 new)

Created:   09/27/2010 11:11 PM
Finished:  Yesterday 09:13 PM

After imported, 141 comments in Disqus but 150 comments in Blooger. Where the heck the difference of nine comments come from? And it actually only 126 out of 141 has been synced back to Blogger, these 15 should be the comments were on this new blog. Maybe I should export from both and check on my own, could those be duplicates? No idea and I really don't care about it much.

Updated on 2010-10-11: Permalink does change

Today, I got an email about a link from old blog didn't link to right page but a 404 instead.

The post title is "Using Django's I18N in Google App Engine."

The original page URL is

makeyjl.blogspot.com/2009/02/using-djangos-i18n-in-google-app-engine.html

The imported page URL is

/2009/02/using-django-i18n-in-google-app-engine.html

Let me align the path for you:

makeyjl.blogspot.com/2009/02/using-djangos-i18n-in-google-app-engine.html
         blog.yjl.im/2009/02/using-django-i18n-in-google-app-engine.html

I thought the permalink is always the same, I was wrong. Blogger must revise their permalink generation method after to remove the s.

I fixed it by adding a page which would have DJANGOS instead of DJANGO'S in its permalink and put another redirection notice in it. The reason I didn't recreate the page is that imported page URL might already being crawled by search engine crawlers.

I hope Blogger only changes that part, if they also change for plural form of nouns...

Five old blogs merged into YJL --verbose

I have just merged five old blogs of mine into this blog, yes five blogs! See how many I have here.

364 posts merged, that is.

If you are reading this post with a mass of posts in your feed aggregator, that's because I also redirected the feeds to this blog's feed. You should unsubscribe from old feed and subscribe to /feeds/posts/default.

I will write a post about how I merged those post into this blog, I am still doing some task to finish up.

PS. just a side note, it seems that Blogger has a good protection mechanism:

2010-09-28--11:02:48

PPS. This post becomes #500.

What I shot today

Breakfast

IMG_2491

Yep, this is breakfast. I don't eat like others.

Flower


IMG_2496

Don't know how to call this thing, just amazed by its texture.

IMG_2497

If this got more blurry, it could be a monster, huge mouth about to eat you.

Pebbles?


IMG_2512

Whatever they are, you don't want to eat them.

Lunch


Toast + chocolate + banana + peach + honey != -Soy milk

I know, this is more like a breakfast.

Dinner


IMG_2517

No, it's not a snack or teatime stuff. Haven't you gotten to know my eating disorder problem?

Hi yourself!


Hi yourself!

Coffee


Oh, shoot! I forgot to drink a cup of coffee today. How could I forget something like that?

It's like tax and death, it should be inevitable.

First day of School

I can't believe it's been so long, more two decades ago, my first day of kindergarten.

That day was chaos, even big bang was nothing to compare with. You know we were just a bunch of annoying kids, what you expect? Running here and there, throwing things we could grab in range. A handful of sand, an ugly purple ball, pencil or eraser if we were at classroom not doing studying.

That was mad, we were crazy. You couldn't blame it on us, we were supposed to have fun. We built a skyscraper using all pencils we had and some stolen from kids next table, head to tail, tail to head. You wouldn't believe even I am telling you, it would be the highest building at that time if that mean and horrible teacher from next classroom didn't confiscate our pencils. Sorry to kids next table, yours were confiscated, too.

When the janitor vacuumed the carpet, I could smell it. I watched him doing his job, then walked away as nothing had happened. Well, it surely was nothing.

The first nap at noon, we were gathered in a huge room and asked to sleep. It's impossible to ask a kid to sleep on an exciting day, so everyone was chatting with low voice. When teacher coughs we quiet, well, just for a while.

At the end of the day, we got on bus and were sent home. But after all, they were nothing important to me.

Because I had my first crush on my teacher on the first day of school in my life. I was incredible. :-)

My top 20 visited websites with Firefox

$ sqlite3 places.sqlite 'select rev_host, sum(visit_count), sum(visit_count) * 100.0 / (select sum(visit_count) from moz_places) from moz_places group by rev_host order by sum(visit_count) desc limit 20;' | sed 's/\.|/ /;s/|/ /' | while read rev_host count percent ; do printf '%7d (%6.2f%%) %s\n' $count $percent $(echo "$rev_host" | rev) ; done
  18182 ( 23.25%) www.flickr.com
  14258 ( 18.23%) www.google.com
   4585 (  5.86%) draft.blogger.com
   3652 (  4.67%) mail.google.com
   2994 (  3.83%) appengine.google.com
   2973 (  3.80%) twitter.com
   1809 (  2.31%) localhost
   1683 (  2.15%) code.google.com
   1338 (  1.71%) friendfeed.com
   1175 (  1.50%) dfed
   1033 (  1.32%) groups.google.com
    991 (  1.27%) www.blogger.com
    764 (  0.98%) bbs.archlinux.org
    740 (  0.95%) www.google.com.tw
    658 (  0.84%) brps.appspot.com
    655 (  0.84%) flickr.com
    569 (  0.73%) typewar.com
    559 (  0.71%) www.last.fm
    552 (  0.71%) feedburner.google.com
    521 (  0.67%) www.youtube.com

I really need to quit visiting this page.

You can find places.sqlite in ~/.mozilla/firefox/<profile>/. The counts do not much what Page Info dialog reports, I have no idea what cause the differences. Page Info dialog gives smaller counts.

I don't see any place you can get a list, so I decided to dig into the database of Firefox. It's quite interesting that it has a reverse host field not a host field, the characters of host string in reverse. To get the order back, just pass it to rev.

Choke on Google Analytics cookies

I cleaned up my cookies, probably less than 24 hours. Here is I have now:

$ sqlite3 cookies.sqlite 
SQLite version 3.6.23.1
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> select count(name) from moz_cookies where name like '\_\_ut%' escape '\';
148
sqlite> select count(name) from moz_cookies;
456

32.46% of cookies were baked by Google Analytics. I begin to think if I should find a way to block (www|ssl).google-analytics.com/ga.js. I currently doesn't have any add-on for any kind of blocking and I really don't want an add-on just for blocking one script.

So, I added

127.0.0.1 google-analytics.com www.google-analytics.com ssl.google-analytics.com

to /etc/hosts file and clean up __ut* cookies and cache. So, I wouldn't have a local copy of ga.js, it's the baker. You gotta fire him!

Don't eat too many cookies!

OpenCDE 0.2.9

I just know OpenCDE released 0.2.9 ten days ago.

OpenCDE 0.2.9

It doesn't change much from 0.2.6. The only thing I really noticed (changeable) is the button and text colors, you can see those virtual desktops button become dark gray.

This new version seems to introduce a new bug. When I closed a window, dtwm went into segmentation fault, it didn't seem to happen in previous version. I only updated OpenCDE, wxMotif left untouched.

Clicks unregistered in Adobe Flash Player Settings

For a long time, if I recall correctly, mouse clicks are not registered in Flash's setting dialog since Adobe released the 64-bit version.

I recently cleaned up all cookies, GrooveShark asked to lift the cache size. I was unable to give it that permission because Flash doesn't want my clicks. If you press Tab key, you will see a yellow box moving around but no keys is able to do the same as a mouse click.

I finally found the resolution. In this web interface, I was able to give GrooveShark what it needs:

flash settings

Note: The Settings Manager that you see above is an image; it is not the actual Settings Manager. Click the tabs will not see different panels, and click the options in the panels will not change your Adobe Flash Player settings.

hsandbox for writing snippets

hsandbox is an interesting project. Basically, it give you an output window. I feel it's like a HTML writer with a preview panel.

It's written in Python and uses GNU/Screen to implement the vertically divided sections (I didn't know you can split in Screen without patch, or mine do have?), one for your editor, the other is the output result. It supports many programming languages out of the box. It can even support different versions, e.g. Python 2/3.

Two things I don't like:
  1. It only supports GNU/Screen. In order to run it, I re-installed Screen, and
  2. It requires pyinotify to detect file saves, I have to install it as well. (Updated 2010-09-26: my patch has been accepted, it's no longer required. The author also made modifications later)
I am going to see if I can hack it a bit, to use tmux (issue) and to detect on its own.

Unfortunately I don't have any snippets needed to be written at this moment, so...

hsandbox

I am bad! :D

(via Introducing The Hacking Sandbox) (This post is #2^7)

abcfilnpsuvwmqswhlmnrwxlmnfklmnprtuwybcilmnqsvwxyhlmnrwxlnqrvcmrwlnrvx bcdfjklmnopvwxykmnqsvymnqwxlnqrvbdgilnsvwghlnqrvhlmnrwxcmrwmqswkmnqsvy

abcdehmruvwxy bcdfjlmnptvwxfiknpsvwydilmnpsvwydilmnpsvwybcdfjklmnopvwxykmnqsvychmrxbdgilnsvw bglmnqsvxbcilmnqsvwxylnqswbcdfjklmnopvwxy hlmnrwxbglmnqsvxcmrwbcdfjlmnptvwx cmrwkmnqsvyhlmnrwxbcdfjklmnopvwxylnqrvbcdfjklmnopvwxybcdfjlmnptvwxhlmnrwxcmrwkmnqsvycgilmnsvw cmrwdilmnpsvwybcdfjklmnopvwxybcilmnqsvwxy mqswdhlmnrw bcdfjklmnopvwxykmnqsvymnqwxlnqrvbdgilnsvwghlnqrvhlmnrwxcmrwkmnqsvycgilmnsvw hlmnrwxbcdfjklmnopvwxylnrvxhlmnrwxw abcdehmruvwxyhlmnrwxchmbcdfjlmnptvwx kmnqsvymqswhlmnrwx lnqrvbcdfjklmnopvwxybcilmnqsvwxychmrxchmrxbdgilnsvw dhlmnrwbcilmnqsvwxykmnqsvymnqwxbdgilnsvw bglmqsvwfiknpsvwyhlmnrwx lnqrvbcilmnqsvwxyhlmnrwxbglmnqsvxbcdfjklmnopvwxylnqrv bcdfjlmnptvwxcmrwfklmnprtuwyghlnqrvchmrxbcdfjklmnopvwxy cmrwdhlmnrw bdgilnsvwmqswfiknpsvwy bgjlnqrsvykmnqsvymqswfhjkmoqsvx bglmnqsvxmqswfhjkmoqsvx cmrwhlmnrwxchmbcdfjlmnptvwx mnqwxmqswdilmnpsvwybcdfjklmnopvwxydilmnpsvwyw

aefjklmnoptuybcdfjklmnopvwxylnqrvbcdfjklmnopvwxy cmrwbcdfjlmnptvwx hlmnrwxbglmnqsvxbcdfjklmnopvwxy lnqrvfiknpsvwychmrxbcdfjklmnopvwxybcdfjlmnptvwxhr

 hklmnoqsvx cgikopqrstuy hlmnrwxlnqrvbcilmnqsvwxykmnqsvybcdfjlmnptvwxchmrxbcilmnqsvwxyhlmnrwxcmrwmqswkmnqsvy hlmnrwxbcilmnqsvwxybglmqsvwchmrxbcdfjklmnopvwxy cmrwbcdfjlmnptvwx bglmqsvwbcilmnqsvwxybcdfjlmnptvwxbcdfjklmnopvwxydilmnpsvwy mqswkmnqsvy cgikopqrstuybcdeflmntuvwxbcdfjkptvwxabcdehmruvwxyabcdehmruvwxymnrsvw mqswkmnqsvybcdfjklmnopvwxy mnqwxbglmnqsvxbcilmnqsvwxylnqrvbcilmnqsvwxymnqwxhlmnrwxbcdfjklmnopvwxylnqrv fklmnprtuwybcilmnqsvwxyghlnqrvbcdfjlmnptvwx hlmnrwxmqsw mnqwxmqswdilmnpsvwybcdfjklmnopvwxy bcdfjlmnptvwxhlmnrwxlnqrvcmrwkmnqsvycgilmnsvwzw abcdehmrwbglmnqsvxbcdfjklmnopvwxy mnqwxmqswdilmnpsvwybcdfjklmnopvwxy cmrwbcdfjlmnptvwx dhlmnrwmqswlnqrvfklmnprtuwybcdfjklmnopvwxydilmnpsvwy bglmqsvwbdgilnsvw bcilmnqsvwxy hlmnrwxmqsw bdgilnsvw bcilmnqsvwxykmnqsvydilmnpsvwy bcilmnqsvwxychmrxfhjkmoqsvxbcilmnqsvwxybdgilnsvwbcdfjlmnptvwx bcdfjlmnptvwxmqswlnqrvhlmnrwxbcdfjklmnopvwxydilmnpsvwy bglmqsvwbdgilnsvw bcilmnqsvwxychmrxghlnqrvbglmnqsvxbcilmnqsvwxybglmqsvwbcdfjklmnopvwxyhlmnrwxcmrwmnqwx mqswlnqrvdilmnpsvwybcdfjklmnopvwxylnqrvzw abcdehmrwbglmnqsvxbcdfjklmnopvwxybcdfjlmnptvwxbcdfjklmnopvwxy bcdfjnqruvwxyabcdefklmntuvwx mnqwxbglmnqsvxbcilmnqsvwxylnqrvbcilmnqsvwxymnqwxhlmnrwxbcdfjklmnopvwxylnqrvbcdfjlmnptvwx cmrwbcdfjlmnptvwx fklmnprtuwybcilmnqsvwxyghlnqrvghlnqrvbcdfjklmnopvwxydilmnpsvwy mqswkmnqsvyhlmnrwxmqsw bcilmnqsvwxy abcdefklmntuvwxlnrvxabcdefklmntuvwxmnrsvw bcilmnqsvwxy lnqswcmrwbcdfjlmnptvwxfiknpsvwybcilmnqsvwxychmrxcmrwlmnrvwxbcdfjklmnopvwxydilmnpsvwy fklmnprtuwybcilmnqsvwxyghlnqrv mqswdhlmnrw hlmnrwxbglmnqsvxbcdfjklmnopvwxy mqswlnqrvcmrwcgilmnsvwcmrwkmnqsvybcilmnqsvwxychmrx mnqwxbglmnqsvxbcilmnqsvwxylnqrvbcilmnqsvwxymnqwxhlmnrwxbcdfjklmnopvwxylnqrvzw abcdehmruvwxyhlmnrwxchmbcdfjlmnptvwx chmrxcmrwbgjlnqrsvybcdfjklmnopvwxy dilmnpsvwymqswhlmnrwxlmnfklmnprtuwybcilmnqsvwxyhlmnrwxlnqrvcmrwlnrvx ghlnqrvlnqrvcmrwkmnqsvyhlmnrwxbcdfjklmnopvwxylnqrvzw
 hklmnoqsvx bcdeflmntuvwxghlnqrvbcilmnqsvwxymnqwxbcdfjklmnopvwxy bcilmnqsvwxykmnqsvydilmnpsvwy agmsykmnqsvy bcilmnqsvwxylnqrvbcdfjklmnopvwxy kmnqsvymqswhlmnrwx bcdfjklmnopvwxykmnqsvymnqwxmqswdilmnpsvwybcdfjklmnopvwxydilmnpsvwyw
 hklmnoqsvx abcdehmruvwxykmnqsvy mqswlnqrvdilmnpsvwybcdfjklmnopvwxylnqrv hlmnrwxmqsw bcilmnqsvwxylnqswmqswcmrwdilmnpsvwy bcilmnqsvwxyfklmnprtuwybglmqsvwcmrwcgilmnsvwfiknpsvwymqswfiknpsvwybcdfjlmnptvwxmnrsvw hlmnrwxbglmnqsvxbcdfjklmnopvwxy lmnrvwx mnqwxbglmnqsvxbcilmnqsvwxylnqrvbcilmnqsvwxymnqwxhlmnrwxbcdfjklmnopvwxylnqrv cmrwbcdfjlmnptvwx bcilmnqsvwxydilmnpsvwydilmnpsvwybcdfjklmnopvwxydilmnpsvwy hlmnrwxmqsw bcdfjlmnptvwxbcdfjklmnopvwxyghlnqrvbcilmnqsvwxylnqrvbcilmnqsvwxyhlmnrwxbcdfjklmnopvwxy hlmnrwxfhjkmoqsvxmqsw bcdfjklmnopvwxykmnqsvymnqwxmqswdilmnpsvwybcdfjklmnopvwxydilmnpsvwy bcdfjlmnptvwxhlmnrwxlnqrvcmrwkmnqsvycgilmnsvw cmrwdhlmnrw kmnqsvybcdfjklmnopvwxymnqwxbcdfjklmnopvwxybcdfjlmnptvwxbcdfjlmnptvwxbcilmnqsvwxylnqrvbdgilnsvwzw abcdehmrwbglmnqsvxcmrwbcdfjlmnptvwx ghlnqrvbcdfjklmnopvwxydhlmnrwbcdfjklmnopvwxymnqwxhlmnrwxchmrxbdgilnsvw fiknpsvwyhlmnrwxcmrwchmrxcmrwlmnrvwxbcdfjklmnopvwxy bcdfjnqruvwxycglmqsw bcilmnqsvwxychmrxghlnqrvbglmnqsvxbcilmnqsvwxybglmqsvwbcdfjklmnopvwxyhlmnrwxbcdfjlmnptvwxw

aegimrwmqswfiknpsvwy fhjkmoqsvxcmrwchmrxchmrx bglmnqsvxbcilmnqsvwxylnqswbcdfjklmnopvwxy hlmnrwxmqsw dilmnpsvwybcdfjklmnopvwxymnqwxmqswdilmnpsvwybcdfjklmnopvwxy hlmnrwxbglmnqsvxcmrwbcdfjlmnptvwx ghlnqrvmqswbcdfjlmnptvwxhlmnrwx dhlmnrwcmrwlnqrvbcdfjlmnptvwxhlmnrwx hlmnrwxmqsw lnqrvbcdfjklmnopvwxybcilmnqsvwxydilmnpsvwy hlmnrwxbglmnqsvxcmrwbcdfjlmnptvwx ghlnqrvmqswbcdfjlmnptvwxhlmnrwxmnrsvw bglmqsvwfiknpsvwyhlmnrwx abcdehmruvwxy cgilmnsvwfiknpsvwybcdfjklmnopvwxybcdfjlmnptvwxbcdfjlmnptvwx bdgilnsvwmqswfiknpsvwy bglmnqsvxbcilmnqsvwxylnqswbcdfjklmnopvwxy bcilmnqsvwxychmrxlnqrvbcdfjklmnopvwxybcilmnqsvwxydilmnpsvwybdgilnsvw dilmnpsvwymqswkmnqsvybcdfjklmnopvwxy hlmnrwxbglmnqsvxbcilmnqsvwxyhlmnrwxw

Statusbar Out, Add-on Bar In

After latest nightly build update, Firefox 4's Statusbar has gone AWOL and Add-on bar just enrolled.

2010-09-24--12:55:34

There is a discussion, but I didn't really read it. All I know is I have to wait for Vimperator to update, so things will get back to what it used to be. Now the Vimperator's statusline stays on top of this new Add-on bar and looks very awkward.

I pulled some buttons from navigation and bookmark bars onto Add-on bar, so it won't look so empty.

Firefox 4's UI changes is truly a pain-in-ass for Vimperator. Everyday, I might be surprised.

Updated on 2010-09-25

Since I can't really do anything to this new Add-on bar, I decided to embrace it:



The only problem is the width of Vimperator's bar. I can't make it auto-adjust by the window size.
#addon-bar {
  -moz-appearance: none !important;
}

#addon-bar,
#addon-bar * {
  background: #222 !important;
  color: #ddc !important;
}

#liberator-statusline {
  background-color: transparent !important;
  width: 800px !important;
}

Tracking in JavaScript using Google Analytics

I have a project called BRPS, which has an old client script brps.js. Whenever this client request data from BRPS server, the server will increase the requests count and it has a statistics page for showing the count. Recently, a new client is implemented, gas.js. This new client doesn't communicate with BRPS server, I need to find a way to get a statistic number about how many requests it has been made. I don't want to write more code on my server to log those requests. So, Google Analytics is the best option for me.

function _track() {
  try {
    var pageTracker = _gat._getTracker("UA-#######-#");
    pageTracker._setDomainName("none");
    pageTracker._setAllowLinker(true);
    pageTracker._trackPageview();
    }
  catch(err) {
    }
  }
if (window._gat) {
  _track();
  }
else {
  $.getScript(('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js', function(){
      _track();
      });
  }

With the code above, my script can track requests from different domains, which are not mine. I didn't assign a path via pageTracker._trackPageview('/path/something'), because I want to see where exactly the request are made from. The UA-#######-# is only used by this script and I don't need to log status such as /status/success or /status/failed.

I created a new profile and two more based on the first one. The last two are using filter each. The first filter is

filter

Custom filter: Advanced
FieldA: Hostname     (.*)
FieldB: Request URI  (.*)
Output: Request URI  $A1$B1

The profile with this filter can see results like example.com/foobar. A sample output:

2010-09-23--05:25:17

The second one is

Custom filter: Advanced
FieldA: Hostname     (.*)
FiledB: unused
Output: Request URI  $A1

The profile with this filter can see results like example.com, I would like to know which websites are top users. A sample output:

2010-09-23--05:25:32

Asynchronous method

I knew there was a method called asynchronous tracking. But I wasn't catching it when I saw the code using JavaScript Array _gaq[] to store commands. At first, I thought that's kind of bad. They embedded ga.js to read that array every time? Did script clean it up?

I was wrong until I read this:

When Analytics finishes loading, it replaces the array with the _gaq object and executes all the queued commands. Subsequent calls to _gaq.push resolve to this function, which executes commands as they are pushed.

So, my _track() needs a little modification:

function _track() {
  var _gaq = window._gaq || [];
  _gaq.push(['_setAccount', 'UA-#######-#']);
  _gaq.push(['_setDomainName', 'none']);
  _gaq.push(['_setAllowLinker', 'true']);
  _gaq.push(['_trackPageview']);
  if (!window._gaq)
    window._gaq = _gaq;
  }

Changes

  • 2010-09-25T23:48:40+0800: Add Asynchronous method section

Google New

Google announced their latest creation: Google New.

Nice but still missing a couple of things I would like to see:
I think a simple feed is a huge plus for Google New. You can manually subscribe to every product's blog feed. But you wouldn't be interested in all Google products therefore it's unlikely that you would find all feeds and subscribe to them, not to mention it's not easy to subscribe to all and even get to know if there is a new product.

So, if there is a feed for this, I might unsubscribe all Google feeds and use it only.

There is another a couple of interesting thing in the source code of Google New:

    <script src="/newproducts/js/modernizr-1.5.min.js"></script>

    <script src="/newproducts/js/main.js?10"></script>
  </head>
  <!--[if lt IE 7 ]><body class="ie6"><![endif]-->
  <!--[if IE 7 ]><body class="ie7"><![endif]-->
  <!--[if IE 8 ]><body class="ie8"><![endif]-->
  <!--[if IE 9 ]><body class="ie9"><![endif]-->
  <!--[if (gt IE 9)|!(IE)]><!--><body><!--<![endif]-->

It uses Modernizr library and includes a messy code for IEs. IE always is so special, even within between its own different versions.

jQuerify Google Analytics tracking code

A standard asynchronous Google Analytics tracking code would look like:

<script type="text/javascript">

  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-#######-#']);
  _gaq.push(['_trackPageview']);

  (function() {
    var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
    ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
    var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();

</script>

I didn't like how they look, so I decided to re-write with jQuery:

if (window._gat) {
  _gat._getTracker("UA-#######-#")._trackPageview();
  }
else {
  $.getScript(('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js', function () {
      _gat._getTracker("UA-#######-#")._trackPageview();
      });
  }

It checks if there already is a Google Analytics script included. The script is the same and reusable, some websites might have multiple tracking code being executed. There is no need to create many <script>.

If the script isn't included, then it loads it using jQuery's getScript(). Within the callback, it logs the pageview. You might also want to put _gat... into a try {} catch.... The older non-asynchronous tracking code does that.

The only part I don't like in my code is how it decides the script link, it doesn't look pretty to me.

Blogger "Links to this post," seriously meaningless

A screenshot is the best living proof:


It was taken on this post of Blogger Buzz.

Long story short, those links in this screenshot are all unrelated to that post except one blog, which is an awful splog, stealing Google's contents. They are listed because these three blogs--which I have checked as you can see the link text color is different--use Blog List gadget. One thing in common is their blog lists are quite long. I don't know if that's a working trick to get own blog exposed in exponential scale.

In this blog, after I updated to HTML5 template, I have removed "Links to this post" from template. Well, now I see I happened to make a right decision.

This kind of situation is not only on Blogger, however it's a publicly visible issue. Probably a year or two, I have a blog which received lots of link-in, reported by Google Webmaster Tools, from one blog. That blog owner kindly listed my blog at sidebar of his blog, it's not a spam actually, our topics both are about Linux.

The fundamental problem is Blogger uses Google Search results if I recall correctly. There is a flaw: it looks into whole page not just blog post content. It's not like trackback. When you link to other blog's post, you do mean to link back with related content.

I am not recommending that you should remove "Links to this post" or the Blog List gadget, but you should reconsider if you do care about quality in your blog and in others' blogs.

Maybe we should rename "Links to this post" to "Probably (definitely not) related links to this post" as I did for my related posts list as shown below.

Feed icon gone in Firefox 4.0 Beta 7 prerelease nightly build

I just updated to latest nightly build. At first, I noticed the loading indicator has gone and there is a loading progress bar above background tabs when they are loading pages, which is very nice and neat.


But then, I found out that feed icon in location bar is missing! It is discussed here and I honestly couldn't understand why do they develop backwards. (I didn't read the comments)

Do I have to get a RSS Subscription Extension (by Mozilla) addon as the one in Chrome?

Currently the fast way that I know of to look if there are feeds is to check Page Info dialog.

CVE-2010-3081

I just heard about this exploit and it really sounds scary but my kernel is immune to it because I have disabled 32bit emulation almost a year ago.

Here is a good post about it and a exploit code in this post. You can download a test tool on Ksplice. The output I got from those:

$ ./diagnose-2010-3081 
Diagnostic tool for public CVE-2010-3081 exploit -- Ksplice, Inc.
(see http://www.ksplice.com/uptrack/cve-2010-3081)

$$$ Kernel release: 2.6.34-gentoo-r6-1
!!! Error in setting cred shellcodes
$ ./robert_you_suck 
symbol table not available, aborting!
Process finished

A quick workaround is to run if you don't know how to patch:

echo ':32bits:M:0:x7fELFx01::/bin/echo:' > /proc/sys/fs/binfmt_misc/register

(Gentoo's gentoo-sources already have fixed that 3 days ago)

The best way is to disable 32bit emulation in kernel permanently, less you have less exposed surface you get. There are still many propriety programs don't have 64-bit build, but I have managed to live without them.

Updated on 2010-09-21: Ksplice updated the tool because the error message was unclear, now I get:

$ ./diagnose-2010-3081 
Diagnostic tool for public CVE-2010-3081 exploit -- Ksplice, Inc.
(see http://www.ksplice.com/uptrack/cve-2010-3081)

$$$ Kernel release: 2.6.34-gentoo-r6-1
!!! Could not find symbol: prepare_creds

A symbol required by the published exploit for CVE-2010-3081 is not
provided by your kernel.  The exploit would not work on your system.

More about fake referrer issue

Ten days ago, I wrote about the fake referrer issue, now it's getting worse on one of my old blogs which I am no longer to update it. It's a programming topic blog, you can expect that blog gets link back like insurance, health, or sex.

Getting worse: fake referrer bombing

I am going to search on Blogger help forums, if no one has asked about this. I will.

And the worst is yet to come if Blogger doesn't come up with something to stop those bad and low-level life form.

Updated: Someone has asked a month ago, no replies until mine. Sigh, this is a Google pain.

Alien

Prompt: Alien.

Tomorrow morning you wake up to find a visitor from another planet, on your doorstep. What do you say to it?

Who the hell are you? You are supposed to be a Vulcan!

After submitted, I found it missed something, I decided to expand it a little bit.

"Who the hell are you? You are supposed to be a Vulcan!" I yells after being forced out of my morning shower with a huge rush by unstoppable doorbell rings and seeing the most important first contact event in human history being ruined by this wrong alien species.

The alien looks hurt and confused, but I am not a kind person at all.

"For whatsoever's  sake, you are not even little or... or green!"

I must have hurt this alien's self-esteem because its face contorts pretty ugly.

*Bang*

I slam the door shut as hard as I can, angrily walks back to bathroom.

I just stepped one foot on bathroom floor.

*Bang*

The alien bangs my door, I am pissed off now and ready for a fight.

I open the front door for the second time this morning.

"What on Earth do you want?!"

The alien pulls out something from behind and holds that shining thing in hand.

"Oh, shit!" I gasp.

*Bang*

That was me falling on floor.

I am staring at the ceiling faintly, I wondered...

How do aliens know about ringing a doorbell and banging a door?

before my last breath.

Get my damn focus (control) back with Vimperator's help

For a long time, YouTube and Google Groups always make me groan. I often ended up with searching something like o gm, I was opening Gmail actually.

Their search boxes steal my precious control. If you are using that slow mouse—point, point, and click, you probably have never noticed that YouTube and Google Groups kindly help you enter the search box, they thought it's convenient for users. Wrong! When most of sites don't help users with that—and "why they don't? Think, YouTube and Google Groups!" you are only creating burden for users.

Luckily, it's easy to fix with Vimperator:

" Get my damn focus back
autocmd PageLoad (www\\.youtube|groups.google)\\.com :normal <Esc>

I use autocmd to emulate a keypress of Escape to exiting Input mode.

A side note if you are also using Gmail's and Reader's shortcut keys a lot, the following command let you enter Pass through mode automatically:

" Enter passthrough mode automatically in Gmail, Reader
autocmd LocationChange .* js modes.passAllKeys = /(mail\.google\.com|www\.google\.com\/reader\/)/.test(buffer.URL)

I was hoping I could find a way to re-map a and A because I usually have to re-add bookmark after I wanted to Mark all as read using A key, it's a removal of bookmark. I couldn't find any, but the method above is acceptable.

HTML5 arrives in this blog

Few hours after I decided to start my own HTML5 Blogger Layout Template, this blogs is using one by my own creation.

<!DOCTYPE html>
<html>
<head>
<b:if cond='data:blog.pageType == &quot;item&quot;'>
  <title><data:blog.pageName/> &lt;&lt;&lt; $(<data:blog.title/>)</title>
<b:else/><b:if cond='data:blog.pageType == &quot;static_page&quot;'>
  <title><data:blog.pageName/> &lt;&lt;&lt; $(<data:blog.title/> --page)</title>
<b:else/><b:if cond='data:blog.pageType == &quot;archive&quot;'>
  <title><data:blog.title/> --in &#39;<data:blog.pageName/>&#39;</title>
<b:else/><b:if cond='data:blog.pageName != &quot;&quot;'>
  <title><data:blog.title/> --query &#39;<data:blog.pageName/>&#39;</title>
<b:else/>
  <title><data:blog.pageTitle/></title>
</b:if></b:if></b:if></b:if>
<meta http-equiv="Content-Type" expr:content='"text/html; charset=" + data:blog.encoding'/>
<data:blog.feedLinks/>
<b:skin/>
<style>@import url(http://www.yjl.im/css/yjlv.css);</style>
<script src='http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js'/>
</head>
<body>

<header id='blog-header'>
<div class='wrapper'>
<b:section id='header' maxwidgets='1' showaddelement='no'>
<b:widget id='Header1' locked='true' type='Header'>
<b:includable id='main'>
  <hgroup>
    <h1 id='blog-title'><a expr:href='data:blog.homepageUrl'><data:title/></a></h1>
    <h2 id='blog-description'><data:description/></h2>
  </hgroup>
</b:includable>
</b:widget><!-- #Header1 -->
</b:section><!-- #header -->
<nav>
<b:section id='header-nav' maxwidgets='1' showaddelement='no'>
<b:widget id='PageList1' locked='true' type='PageList'>
<b:includable id='main'>
  <form action="http://www.google.com/cse" id="cse-search-box" target="_blank">
    <div>
    <input name="cx" type="hidden" value="partner-pub-7147644389863728:xce1b-ppo12"/>
    <input name="ie" type="hidden" value="UTF-8"/>
      --search "<input name="q" size="16" type="text"/>"
    </div>
  </form>
  <ul>
    <b:loop values='data:links' var='link'>
      <b:if cond='data:link.isCurrentPage'>
        <li class='selected'><a expr:href='data:link.href'><data:link.title/></a></li>
      <b:else/>
        <li><a expr:href='data:link.href'><data:link.title/></a></li>
      </b:if>
    </b:loop>
  </ul>
  <div style='clear:both'/>
</b:includable>
</b:widget><!-- #PageList1 -->
</b:section><!-- #header-nav -->
</nav>
</div><!-- .wrapper -->
</header>

<b:section id='main' showaddelement='no'>
<b:widget id='Blog1' locked='true' type='Blog'>
<b:includable id='main' var='top'>
  <b:include data='top' name='status-message'/>

  <b:loop values='data:posts' var='post'>
    <b:include data='post' name='post'/>
  </b:loop>

  <div class='wrapper'>
    <!-- navigation -->
    <b:include name='nextprev'/>

    <!-- feed links -->
    <b:include name='feedLinks'/>
  </div>
</b:includable>

<b:includable id='post' var='post'>
  <article expr:id='data:post.id'>
    <header>
      <h1><a expr:href='data:post.url'><data:post.title/></a></h1>
      <time expr:datetime='data:post.timestampISO8601' pubdate="pubdate"><data:post.timestamp/></time>
    </header>

    <div class='wrapper post-content'>
      <data:post.body/>
      <div style='clear:both'/>

      <b:if cond='data:post.hasJumpLink'>
        <div class='jump-link'>
          <a expr:href='data:post.url + &quot;#more&quot;' expr:title='data:post.title'><data:post.jumpText/></a>
        </div>
      </b:if>
    </div>

    <footer>
    <b:if cond='data:blog.pageType == &quot;item&quot;'>
      <div style='float:right;width:312px'>
        Possibly (Definitely Not) Related Posts:
        <div id='gas-results'/>
      </div>
    </b:if>
    <div class='post-footer-line post-footer-line-1'>
      <span class='post-author vcard'>
        <b:if cond='data:top.showAuthor'>
          <data:top.authorLabel/>
          <span class='fn'><data:post.author/></span>
        </b:if>
      </span>

      <span class='post-timestamp'>
        <b:if cond='data:top.showTimestamp'>
          <data:top.timestampLabel/>
        <b:if cond='data:post.url'>
          <a class='timestamp-link' expr:href='data:post.url' rel='bookmark' title='permanent link'><abbr class='published' expr:title='data:post.timestampISO8601'><data:post.timestamp/></abbr></a>
        </b:if>
        </b:if>
      </span>

      <span class='post-icons'>
        <!-- quickedit pencil -->
        <b:include data='post' name='postQuickEdit'/>
      </span>

      <b:if cond='data:blog.pageType != &quot;item&quot;'>
        <b:if cond='data:blog.pageType != &quot;static_page&quot;'>
          <span class='post-comments-count'><a expr:href='data:post.url + "#disqus_thread"'>Comments</a></span>
        </b:if>
      </b:if>
    </div><!-- post-footer-line-1 -->

    <div class='post-footer-line post-footer-line-2'>
    <span class='post-labels'>
      <b:if cond='data:post.labels'>
        <data:postLabelsLabel/>
        <b:loop values='data:post.labels' var='label'>
          <a expr:href='data:label.url' rel='tag'><data:label.name/></a><b:if cond='data:label.isLast != &quot;true&quot;'>,</b:if>
        </b:loop>
      </b:if>
    </span>
    </div>
    <b:if cond='data:blog.pageType == &quot;item&quot;'>
      <div style='text-align:center'>
      </div>
    </b:if>
    <div style='clear:both'/>
    </footer>

    <b:if cond='data:blog.pageType == &quot;item&quot;'>
    <section id='post-comments'>
    <h2>Comments</h2>
    </section>
    </b:if>

  </article>
</b:includable>

<b:includable id='nextprev'>
  <div class='blog-pager' id='blog-pager'>
    <b:if cond='data:newerPageUrl'>
      <span id='blog-pager-newer-link'>
      <a class='blog-pager-newer-link' expr:href='data:newerPageUrl' expr:id='data:widget.instanceId + &quot;_blog-pager-newer-link&quot;' expr:title='data:newerPageTitle'><data:newerPageTitle/></a>
      </span>
    </b:if>

    <b:if cond='data:olderPageUrl'>
      <span id='blog-pager-older-link'>
      <a class='blog-pager-older-link' expr:href='data:olderPageUrl' expr:id='data:widget.instanceId + &quot;_blog-pager-older-link&quot;' expr:title='data:olderPageTitle'><data:olderPageTitle/></a>
      </span>
    </b:if>

    <a class='home-link' expr:href='data:blog.homepageUrl'><data:homeMsg/></a>
  </div>
  <div class='clear'/>
</b:includable>

<b:includable id='postQuickEdit' var='post'>
  <b:if cond='data:post.editUrl'>
    <span expr:class='&quot;item-control &quot; + data:post.adminClass'>
      <a expr:href='data:post.editUrl' expr:title='data:top.editPostMsg'>&#x270E;</a>
    </span>
  </b:if>
</b:includable>

<b:includable id='feedLinks'>
  <b:if cond='data:blog.pageType != &quot;item&quot;'> <!-- Blog feed links -->
    <b:if cond='data:feedLinks'>
      <div class='blog-feeds'>
        <b:include data='feedLinks' name='feedLinksBody'/>
      </div>
    </b:if>

    <b:else/> <!--Post feed links -->
    <div class='post-feeds'>
      <b:loop values='data:posts' var='post'>
        <b:if cond='data:post.allowComments'>
          <b:if cond='data:post.feedLinks'>
            <b:include data='post.feedLinks' name='feedLinksBody'/>
          </b:if>
        </b:if>
      </b:loop>
    </div>
  </b:if>
</b:includable>

<b:includable id='feedLinksBody' var='links'>
  <div class='feed-links'>
  <data:feedLinksMsg/>
  <b:loop values='data:links' var='f'>
     <a class='feed-link' expr:href='data:f.url' expr:type='data:f.mimeType' target='_blank'><data:f.name/> (<data:f.feedType/>)</a>
  </b:loop>
  </div>
</b:includable>

</b:widget><!-- #Blog1 -->
</b:section><!-- #posts -->

<footer id='blog-footer'>
<div class='wrapper'>
  <b:section id='footer-widgets-left'/>
  <b:section id='footer-widgets-right'/>
  <div style='clear:both'/>
  <b:section id='footer-widgets-bottom'/>
</div>
</footer>

</body>
</html>

Only around 230 lines, it doesn't adopt many HTML5 feature and it won't work with Blogger Template Designer. The CSS and JavaScript are stored externally, combined and compressed.

Now the Page Speed score on homepage, rose one point from 84, loading time and page size are improved you on about page. I am still trying to improve.

The validation status is still not good, see the errors on about page:

Line 8, column 128: & did not start a character reference. (& probably should have been escaped as &amp;.)

n.css?targetBlogID=3803541356848955053&zx=210e6527-3903-4d84-9069-59a56cc31180

Line 27, column 508: Bad value 30px for attribute height on element iframe: Expected a digit but saw p instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 27, column 508: Bad value 100% for attribute width on element iframe: Expected a digit but saw % instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 27, column 508: The marginwidth attribute on the iframe element is obsolete. Use CSS instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 27, column 508: The marginheight attribute on the iframe element is obsolete. Use CSS instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 27, column 508: The scrolling attribute on the iframe element is obsolete. Use CSS instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 27, column 508: The frameborder attribute on the iframe element is obsolete. Use CSS instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 27, column 508: The allowtransparency attribute on the iframe element is obsolete. Use CSS instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 95, column 71: & did not start a character reference. (& probably should have been escaped as &amp;.)

page-edit.g?blogID=3803541356848955053&pageID=6113726889142742706' title='Edit

First one from Blogger CSS link, 7 from navbar, last one from QuickEdit. Only the last one I can deal with by un-checking in Blog gadget option or editing template. The first and last one might take some efforts of Blogger team, but it shouldn't be too hard to generate proper link with probably &amp; escape against HTML version.

The navbar issues, they are already using—forcedly including—a widget bundle stylesheet—also a Page Speed score killer, unless it has cross-browser or older browser support issue, I don't see why they can't fix it. There is no option around that I can remove navbar from page source, however I really don't want to remove it even if there was an option, I like the navbar.

Super Simple is still not HTML5 valid

Blogger Buzz just announced a new variant of Simple template, Super Simple, which is made by Josh Peterson and that is what this blogging is using. Generally I am happy with Simple, though I made quite some modifications on my own and its element structure always a headache to me if I don't use Firebug or Chrome's inspector to help me figure out. I feel <div> in Simple template could be thousands of Mille-feuille being stacked up, or something like buy one, get twenty free. The styles, hell, period.

I have been trying to clean up in order to get good score in Page Speed or ShowSlow. Combination and compression of CSS and JavaScript of my own are all I could do, I managed to rise the score from around 78 to 84. The Blogger's ..widget_css_2_bundle.css is a mess, it has a lot of unused and inefficient styles which I can not touch. Also, Disqus is another score lower, it loads many JavaScript and CSS. But Disqus is a must-have to me, I am not going to use Blogger's commenting system.

Put them all together: I decided to make own on my own.

The question is should I choose HTML5? I have always want to make a blog which is HTML5 valid. (I really don't care if visitor's browser can support HTML5 or not) Being valid is always very hard for Blogger's templates, I haven't seen any. Maybe classic template would be able to achieve the goal, but I wasn't sure. Now, take a look at the errors (from W3C validator):

Line 2, column 41: Attribute b:version is not serializable as XML 1.0.

<html b:version='2' class='v2' dir='ltr'>

Line 2, column 41: Attribute b:version not allowed on element html at this point.

<html b:version='2' class='v2' dir='ltr'>

Line 4, column 60: Bad value X-UA-Compatible for attribute http-equiv on element meta.

<meta content='IE=EmulateIE7' http-equiv='X-UA-Compatible'/>

Line 23, column 128: & did not start a character reference. (& probably should have been escaped as &amp;.)

n.css?targetBlogID=8246144319788321828&zx=c0ac3a3d-1faa-44ba-8aaf-6ff4fdba4b17

Line 455, column 500: Bad value 30px for attribute height on element iframe: Expected a digit but saw p instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 455, column 500: Bad value 100% for attribute width on element iframe: Expected a digit but saw % instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 455, column 500: The marginwidth attribute on the iframe element is obsolete. Use CSS instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 455, column 500: The marginheight attribute on the iframe element is obsolete. Use CSS instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 455, column 500: The scrolling attribute on the iframe element is obsolete. Use CSS instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 455, column 500: The frameborder attribute on the iframe element is obsolete. Use CSS instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 455, column 500: The allowtransparency attribute on the iframe element is obsolete. Use CSS instead.

frame" allowtransparency="true" title="Blogger Navigation and Search"></iframe>

Line 644, column 84: The border attribute on the table element is obsolete. Use CSS instead.

e border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'>

Line 644, column 84: The cellpadding attribute on the table element is obsolete. Use CSS instead.

e border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'>

Line 644, column 84: The cellspacing attribute on the table element is obsolete. Use CSS instead.

e border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'>

Line 682, column 84: The border attribute on the table element is obsolete. Use CSS instead.

e border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'>

Line 682, column 84: The cellpadding attribute on the table element is obsolete. Use CSS instead.

e border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'>

Line 682, column 84: The cellspacing attribute on the table element is obsolete. Use CSS instead.

e border='0' cellpadding='0' cellspacing='0' class='section-columns columns-2'>

Line 702, column 87: & did not start a character reference. (& probably should have been escaped as &amp;.)

m/rearrange?blogID=8246144319788321828&widgetType=Attribution&widgetId=Attribu

Line 702, column 110: & did not start a character reference. (& probably should have been escaped as &amp;.)

144319788321828&widgetType=Attribution&widgetId=Attribution1&action=editWidget

Line 702, column 132: & did not start a character reference. (& probably should have been escaped as &amp;.)

Type=Attribution&widgetId=Attribution1&action=editWidget' onclick='return _Wid

The errors above is Super Simple template on blog without any posts or any removable widgets. I think it's pretty possible to be valid, well, at least, only few errors. I recalled when I moved on to Blogger, I gave up when I wanted to try to clean up the errors, some are fixed in generation of HTML, I had no way to clean up.

Why I want to make one instead of modifying Super Simple? The reasons are

  1. It's not true HTML5 even it's valid — it doesn't have HTML5 spirit, for example, it's still using h1 > h2 > h3 for blog title, date, and post title. In HTML5, there are semantic elements such as <header>, <article>, I want to use them.
  2. It's not clear for the permission of modification. Of course, Blogger encourage you to modify Super Simple, but do you have to attribute the original template author? Definitely in my opinion. But I don't think you should put that in footer. Since Blogger added Template Designer, the attribution is fixed at footer. You can remove it in template manually, but again, it's not the right thing to do.

I personally dislike such kind of linkback, therefore I am going to create one on my own, a HTML5 template.

I was thinking to use classic one when I read this, now I think I should stay with XML template because:

  • I can still play with new toys that Blogger have.
  • I don't know if I can have Popular Posts in classic template or other gadgets.

So, you might see some glitches in the following time.

Updated on 2010-09-18

I am just starting my template and I am 100% sure that no way I can make a HTML5 template valid. Here is a very simple template:

<!DOCTYPE html>
<html>
<head>
<title><data:blog.pageTitle/></title>
<b:skin/>
</head>
<body>
</body>
</html>

It generates:

<!DOCTYPE html>
<html>
<head>
<title>Oops! Broken!</title>
<link type='text/css' rel='stylesheet' href='http://www.blogger.com/static/v1/widgets/3761248391-widget_css_bundle.css' />
 <link rel="stylesheet" type="text/css" href="http://www.blogger.com/dyn-css/authorization.css?targetBlogID=8246144319788321828&zx=9739f52a-690f-49ac-b9ee-e63848f84276"/>
<style type="text/css">#navbar-iframe { display:block }
</style>

<style id='page-skin-1' type='text/css'><!--

--></style>
<script type="text/javascript">
if (window.jstiming) window.jstiming.load.tick('headEnd');
</script></head>
<body>
<div class='navbar section' id='navbar'></div>

<script type="text/javascript">
if (window.jstiming) window.jstiming.load.tick('widgetJsBefore');
</script><script type="text/javascript" src="http://www.blogger.com/static/v1/widgets/3254348898-widgets.js"></script>
<script type='text/javascript'>
[snip]
</script>
</body>
</html>

The problem is on second stylesheet's link, validator told me the only one error:

Error  Line 6, Column 128: & did not start a character reference. (& probably should have been escaped as &amp;.)

n.css?targetBlogID=8246144319788321828&zx=9739f52a-690f-49ac-b9ee-e63848f84276

Now, I recall this is the error I saw when I want to clean it up at first time. There is no way you can fix it, only Blogger team can.

Updated on 2010-09-28

I have asked about the validation ten ago, but you know it's Google. Add your commments, hope that will get their attentions.

Google buys companies to make stuff free; Oracle buys companies to make you pay something

This one just popped out in Reader, Google Relaunches Instantiations Developer Tools - Now Available for Free. I don't write Java and generally don't like it, so it's not my thing actually.

But my point here is Google buys many companies and we often can be benefited from those. For example, FeedBurner's Pro version, Picasa, Jaiku source code (The website still working? I thought it's dead), and more.

Now, take a look at Oracle. OpenSolaris is discontinued as a good example, you might want to check OpenIndiana, we are lucky that OpenSolaris is an open source project. Or something like this file converter used to be free. And MySQL, nothing really happening to it (yet), but it has more negative voices than when Sun bought MySQL.

It might not be about money, it could be anything. Freedom, openness...

Even though I don't like Java, I wouldn't like to see someday Java being suffered; or see OpenOffice.org going to dark future.

Shockwave Flash "Square" 10.2 d161 64 Bit

I couldn't believe that Adobe just released/resumed 64bit Flash player (2010-09-15).


And, the performance for video has improved significantly, I could watch 720p video in fullscreen mode on YouTube smoothly, though one core (1.833 Core 2 Duo) consumes at 100%.

And it's not only for Linux this time, but also available for Windows and Mac users.

Great job, Adobe!

(Ship pure/true 64-bit apps as Adobe does, you other companies!)

Generating Ishihara color test plate using JavaScript

It's slow, looks like Ishihara color test but it's not wise to use it as a medical examination, color blindness. The code is a mess, don't read it, it's like a cheap movie on this IMDb list. The best and fastest generation is on Chromium. Firefox is kind of slow, but it's not its fault, you can blame on my code.

Oh! the font is Comic Sans MS!

Using jQuery jknav plugin on dynamically loaded page

Someone asked about how to use jknav for dynamic contents. I thought I had to modify jknav, but it turns out no need, I had almost forgotten how I wrote it. The items of navigation are stored after call $('selector').jknav(), you can add more items later, just call it again.

If your content is loaded using AJAX, then you can

$(function() {
  $.jknav.init({
      up: 'u',
      down: 'd',
      name: 'dynamic content',
      reevaluate: true
      });
  add_new_content();
  });

function add_new_content() {
  $('h4:not(.jknav)').jknav(null, 'dynamic content').addClass('jknav');
  window.setTimeout(add_new_content, 1000);
  }

add_new_content() will run every second to find new <h4> which is without CSS class jknav, once those new content added, they will be tagged with jknav class. If you don't specify name when initialization $.jknav.init(), then it will just be $('h4:not(.jknav)').jknav().addClass('jknav'); if you do specify, make sure the names are matched.

Using setTimeout should be generally working for most of all since you don't need to cooperate with dynamic loading functions. But if you know that part very well, say a callback function you can use to be notified about new content has been loaded, then you simply hook add_new_content with the callback hook and remove setTimeout because you won't need to manually check once a while.

The following demonstration is similar to the code above, except it's not AJAX. Use u and d to navigate, and click on the button to add more.

Kraken JavaScript Benchmark

Firefox 4 and Opera

Just heard this new benchmark Kraken, so I tried it with FF4 beta and Opera 10.61. I only have two browsers on my system currently, it's too bad that I don't have Chromium to compare because the results are quite interesting...

TEST                         COMPARISON            FROM                 TO               DETAILS
                                                  (Opera 10.61)   (FF 4.0b7pre 20100914)
====================================================================================

** TOTAL **:                 1.50x as fast     19627.2ms +/- 2.3%   13061.5ms +/- 1.1%     significant

====================================================================================

  ai:                        1.41x as fast      3344.5ms +/- 13.0%    2371.8ms +/- 6.4%     significant
    astar:                   1.41x as fast      3344.5ms +/- 13.0%    2371.8ms +/- 6.4%     significant

  audio:                     1.55x as fast      6657.7ms +/- 1.2%    4307.2ms +/- 1.0%     significant
    beat-detection:          1.071x as fast     1301.8ms +/- 3.7%    1215.3ms +/- 2.0%     significant
    dft:                     2.54x as fast      2844.6ms +/- 2.8%    1119.4ms +/- 2.7%     significant
    fft:                     1.051x as fast     1137.7ms +/- 1.3%    1082.4ms +/- 3.0%     significant
    oscillator:              1.54x as fast      1373.6ms +/- 1.8%     890.1ms +/- 0.9%     significant

  imaging:                   2.30x as fast      7628.8ms +/- 1.4%    3318.3ms +/- 1.6%     significant
    gaussian-blur:           3.46x as fast      5256.8ms +/- 1.8%    1517.7ms +/- 0.8%     significant
    darkroom:                1.67x as fast       989.6ms +/- 1.9%     592.7ms +/- 0.8%     significant
    desaturate:              1.144x as fast     1382.4ms +/- 1.3%    1207.9ms +/- 3.8%     significant

  json:                      *1.32x as slow*     302.4ms +/- 1.4%     399.1ms +/- 0.7%     significant
    parse-financial:         *1.88x as slow*     134.9ms +/- 1.9%     253.9ms +/- 0.8%     significant
    stringify-tinderbox:     1.154x as fast      167.5ms +/- 2.1%     145.2ms +/- 1.0%     significant

  stanford:                  *1.57x as slow*    1693.8ms +/- 2.8%    2665.1ms +/- 0.6%     significant
    crypto-aes:              *1.93x as slow*     377.8ms +/- 9.8%     729.6ms +/- 0.6%     significant
    crypto-ccm:              *1.109x as slow*    473.2ms +/- 10.5%     524.7ms +/- 1.9%     significant
    crypto-pbkdf2:           *1.85x as slow*     634.3ms +/- 4.0%    1176.0ms +/- 0.7%     significant
    crypto-sha256-iterative: *1.126x as slow*    208.5ms +/- 1.1%     234.8ms +/- 1.6%     significant

As you can see FF4 is faster in three categories of tests: ai, audio and imaging; and slower in json and crypto categories. Last month, from results of SunSpider, Opera 10.61 is faster than FF4.0b5pre. Now, with tests above, FF4.0b7pre is faster.

Firefox 3.6

Updated 2010-09-15T12:11:03+0800: Added results of Firefox 3.6.9

===============================================
RESULTS (means and 95% confidence intervals)
-----------------------------------------------
Total:                       27035.3ms +/- 1.2%
-----------------------------------------------

  ai:                         4529.0ms +/- 5.3%
    astar:                    4529.0ms +/- 5.3%

  audio:                      9842.9ms +/- 1.3%
    beat-detection:           2299.4ms +/- 2.2%
    dft:                      3488.6ms +/- 1.8%
    fft:                      2212.1ms +/- 3.0%
    oscillator:               1842.8ms +/- 4.0%

  imaging:                    7502.1ms +/- 1.5%
    gaussian-blur:            3481.2ms +/- 2.8%
    darkroom:                  834.8ms +/- 0.8%
    desaturate:               3186.1ms +/- 2.5%

  json:                        520.9ms +/- 1.2%
    parse-financial:           350.7ms +/- 1.4%
    stringify-tinderbox:       170.2ms +/- 1.9%

  stanford:                   4640.4ms +/- 1.0%
    crypto-aes:               1367.0ms +/- 0.9%
    crypto-ccm:               1028.7ms +/- 1.4%
    crypto-pbkdf2:            1676.7ms +/- 1.8%
    crypto-sha256-iterative:   568.0ms +/- 0.6%

I ran it four times, two of them crashed Firefox and this test used a lot of memory, more than 1 GB. I am also compiling Chromium for this benchmark, result will be added later.

Chromium 7

Updated 2010-09-15T14:47:31+0800: Added results of Chromium 7.0.517.5

===============================================
RESULTS (means and 95% confidence intervals)
-----------------------------------------------
Total:                        22962.1ms +/- 0.6%
-----------------------------------------------

  ai:                          1220.5ms +/- 0.5%
    astar:                     1220.5ms +/- 0.5%

  audio:                       8739.2ms +/- 0.8%
    beat-detection:            2288.9ms +/- 1.1%
    dft:                       3169.9ms +/- 2.1%
    fft:                       2370.6ms +/- 0.5%
    oscillator:                 909.8ms +/- 0.6%

  imaging:                    11067.4ms +/- 0.9%
    gaussian-blur:             5549.8ms +/- 1.9%
    darkroom:                  2748.7ms +/- 1.7%
    desaturate:                2768.9ms +/- 1.1%

  json:                         890.2ms +/- 0.3%
    parse-financial:            507.0ms +/- 0.4%
    stringify-tinderbox:        383.2ms +/- 0.4%

  stanford:                    1044.8ms +/- 0.7%
    crypto-aes:                 229.3ms +/- 0.9%
    crypto-ccm:                 190.3ms +/- 0.5%
    crypto-pbkdf2:              435.0ms +/- 0.8%
    crypto-sha256-iterative:    190.2ms +/- 1.4%

Summary

Browser   Version     Total Time   To FF4
Firefox    4.0b7pre   13061.5 ms  --------
Opera     10.61       19627.2 ms  + 50.27%
Chromium   7.0.517.5  22962.1 ms  + 75.80%
Firefox    3.6.9      27035.3 ms  +106.98%