CanvasBlock: a GM script to block canvas tag (should we…or can we?)

April 13th, 2010  |  Published in Uncategorized  |  1 Comment

HTML5 is believed to be the Flash killer and will replace Flash in the future. Eventually those Flash-haters will become canvas-haters, so a canvas-blocking GreaseMonkey script will be useful (at least they think it will be).

I myself was making it for fun. I don’t think we should block any HTML5 tags anytime since it is a part of the web, just like I do not agree people blocking Flash. What is interesting is, seems like we cannot effectively block the canvas tag, which will be discussed later in this post.

Features

I made the script blocks not only canvas tag but also video tag and audio tag. It is because Flash is going to be replaced by all the three tags but not only canvas. Video and audio can be as annoying as canvas.

Like those Flash-blockers, the blocked contents are replaced by a line of text, “Click to show xxxx”. You may click on it to get back the blocked content.

CanvasBlock is tested on FireFox 3.6 on Mac, FireFox 3.5 on Ubuntu and Chrome on Ubuntu. Other platforms should works too.

Implementing the script

I used haXe instead of writing pure JS. No big reason here, just to see if it is possible. Turn out there is no big difference from using JS, you just need to copy all the meta data to the compiled JS file. And the events listener need to be assigned by “addEventListener” instead of something like “onclick = function …”.

Detecting HTML5 tags is easier than detecting Flash objects. Firstly, the tags are standardized meaning you can simply use “getElementsByTagName”. For Flash objects you need to check the params of the “object” and the “embed” tags, which is a bit troublesome. Secondly, currently no one (at least not much ppl) is creating canvas tags on the fly, unlike for Flash the standard way is to use swfobject. So I can detect the tags once the DOM is ready, no need to wait for the execution of the page’s JS.

Replacing the tags and saving them for later retrieval is easy too. Using normal JS method will work.

The tags are blocked but…

The script is functional and I went to do some more testing. Blocking video and audio seems ok, but there is some problem of blocking canvas.

Possibility of Freezing/Crashing

I went to ChromeExperiments and randomly picked one. You know what? The browser freezed.

So, look like after I blocked the canvas, the JS on the page which is used to draw thing on the canvas originally, is still there trying to work on the canvas. And this become a big problem since I don’t know exactly which JS function is going to work on canvas, because different web page have different functions, so no way I can work on that. You can completely disable JS, but this is not a CanvasBlock should do.

Browser freezed and an timeout message was shown after blocking canvas.

However, I have tested some more web page and they are ok with the blocking script. So maybe only some complex JS will have this problem. But anyway the possibility of freezing a browser is not a good thing.

No significant reduction on CPU usage

The remaining JS script  problem reminded me to test on the CPU usage. And the result is, blocking canvas does not bring significant reduction on CPU usage. See the following screenshots, which is using another Chrome experiment:

Page opened, canvas blocked. However CPU usage still rise to a very high level.

Clicked to show back the canvas. CPU usage rose even higher, but not much difference.

So what’s that mean? Again if I want to block the real CPU hog, I should block the JS with the canvas. But again, stated above, it is not possible to block the right function without blocking all JS.

Conclusion

Blocking canvas can only introduce little benefit on CPU usage but give you possibility of freezing/crashing!

Let’s look at Flash again. Flash can be blocked easily because ActionScript is included in the swf. Removing the swf from the page automatically removes the associated scripts. Also, usually JS does not control a Flash object so it is pretty safe to kick Flash out without dealing with the remained JS. From this point of view, seems that Flash is more user friendly than canvas, and HTML5 ads will be more annoying than Flash ads…

If you want to try, you may install the script from CanvasBlock’s page on userscripts.org.

You’re also welcome to get the haXe source from CanvasBlock’s github repo.

Tags: , , ,

CasaHx – CASA Lib for haXe

April 6th, 2010  |  Published in Uncategorized  |  2 Comments

I’ve mentioned that I was porting CASA Lib for AS3 to haXe in the last blog post. I’m happy to tell you that it is finished and has been uploaded to haxelib.

If you’re not familiar with it, it has a set of display object classes that have build in methods for removing all listeners/all children, and a destroy method that do that all in once. There are also simple tweening classes, layout helper and a huge set of utilities.

I try to make all the classes as cross-target as possible so that you can use it in JS/C++/PHP/Neko (some of them need nme/neash/canvas-nme).

With haXe’s “using” keyword, the utility classes are even sweeter than the AS3 version. Let’s take an example form the official documentation(in AS3):

var people:Array = new Array(	{name: "Aaron", sex: "Male", hair: "Brown"},
				{name: "Linda", sex: "Female", hair: "Blonde"},
				{name: "Katie", sex: "Female", hair: "Brown"},
				{name: "Nikki", sex: "Female", hair: "Blonde"}	);
 
var person:Object = ArrayUtil.getItemByKeys(people, {sex: "Female", hair: "Brown"});
trace(person.name); // Traces "Katie"

Now you can write it in haXe in this way:

using org.casalib.ArrayUtil;
 
var people = [	{name: "Aaron", sex: "Male", hair: "Brown"},
		{name: "Linda", sex: "Female", hair: "Blonde"},
		{name: "Katie", sex: "Female", hair: "Brown"},
		{name: "Nikki", sex: "Female", hair: "Blonde"}	];
 
var person = people.getItemByKeys({sex: "Female", hair: "Brown"});
trace(person.name); // Traces "Katie"

Note that with “using”, auto-completion can also show the added methods (from ArrayUtil, for the above example).

I’ve also typed all the methods. That means, for ArrayUtil.getItemByKeys() with a Array<Point> input, its output will be typed as Point. Nice feature of haXe isn’t it?

PS. Aaron Clinger, the author of CASA Lib, has found me some days ago. He is very nice that may put CasaHx as the official branch of CASA Lib when it is mature enough :)

Tags:

Sandy3D, C++, Haxe

March 18th, 2010  |  Published in Uncategorized  |  1 Comment

I’ve been learning Haxe since the last few months. Beside the reason of many Flash guys moved/moving to Haxe because of better performance of compiled swf, I was tempted to try using its C++ target, which runs even faster(at least in theory, in most parts). Its language feature is also very nice, which is quite similar to AS3 but more powerful in many aspects. Check out its feature page if you want to know more.

And because of I need to write some 3D stuff in a project, I tried finding a Haxe 3D engine  that can compiled to C++, but who knows, there wasn’t one. Actually the 3D engines in Haxe are all quite young. There are 3 I found, all targeting only Flash: Sandy3D, originally written in AS, has switched its trunk to Haxe; Away3D, again originally written in AS, now has a Haxe branch inside its SVN in active development; Haxe3D, developed by Nicolas(the creator of Haxe), written in Haxe from the very beginng, seems to be very light-weight but I can’t found much info about it.

So I decide to work on one of them to enable a Haxe C++ 3D engine. Because Sandy3D should be the most complete and stable one(which actually stopped active development…), I chose it.

In the development of it, some issues are related to nme/neash, which are the re-invented cross-platform Haxe version of the Flash API. With the help from Hugh and Niel, project owner of neash and developer of Sandy3D, most of the problems are solved. However as I can see, re-inventing the Flash API is a hard job as consideration of other target is also needed, eg. JS/Canvas. I really hope Adobe can help this.

Currently some very basic demos of Sandy can be compiled to C++ and it shows that, in OpenGL rendering mode, the performance can goes over 300% of the Flash(Haxe, not AS3) version. However in normal rendering mode, the frame rate may actually be reduced if the window size is large. Anyway, I think the performance is quite depend on hardware/OS, also the 3D scene you’re showing.

Thanks for the Sandy3D team, they added me as a committer in their official Google project. And I have just committed the changes to the trunk :) There should be a new release soon if everything is fine.

A note to the ones can’t wait for a release:

1.Install hxcpp, nme, neash from haxelib.

2.Replace contents in neash’s neash/display/IBitmapDrawable.hx to a simple “typedef IBitmapDrawable =
nme.display.IBitmapDrawable;”.

3.To make mouse event work, in neash’s neash/Lib.hx, the code:

// Process pending timers …
neash.Timer.CheckTimers();
// Send frame-enter event
var event = new Event( Event.ENTER_FRAME );
mStage.Broadcast(event);

should be moved to the end of the do-while loop, just before the:

mStage.RenderAll();

4.For mouse event in opengl mode to work, additional fix which required a recompile of nme is needed. I haven’t tried
yet. Now just ingore this…

5.You should be able to use Sandy3D in C++ without the above patches for the next release of nme/neash. But for now, please do it.

BTW, I am also porting ported casalib, which I often use in AS3 development, to Haxe, see casahx.

Tags: , ,