Archive for October, 2007

Adjust video playback speed

I open this screencast (and I love to watch screencasts before trying the demo). And I see it is 10 minutes long, it has no chapter markers and I don’tknow which parts I can skip to really only see what I am interested in.
So let me just adjust the playback speed! That would be so cool! Whenever I think it’s interesting I just slow down the video speed (if I have not yet gotten used to the speed :-)).
Just give it to me I am an information junkie, but I need to consume faster, so I can consum more!

Comments (3)

Prism, one process per web app

I always wanted this! A stand-alone web application, kinda. I just mean put gmail into it’s own application, so I can separatly launch it from the rest, especially when the browser crashes I don’t want to reopen all the sites, or reconnect my meebo, etc.
Prism, a mozilla labs project, is here to do it. Great I will follow that! When is that coming based on WebKit?

Comments

JavaScript performance talk - must see

Joseph Smarr from Plaxo was holding a talk about High-performance JavaScript: Why Everything You’ve Been Taught Is Wrong. His blog with some background info is here. So many true things and some new things, very interesting to watch if you are interested in tweaking your AJAX app to be performing great.

It was especially interesting to hear one thing that I also found out in my current project, it was “do DOM manipulation off-DOM”. Which means if you are doing some “heavy” DOM manipulation you should ie. copy the DOM element into an absolute positioned element (so that it doesn’t effect all the other elements that are floating around it) and manipulate it there. What I did in this case, was just simply setting visibility to hidden, so I can manipulate and evaluate all the parameters (such as layer size, position, etc. mostly using dojo.corrds()) and when done calculating I simply apply it to the original element. In our case we were resizing fonts to best fit in a box. And it made a noteable difference in performance to make the font size manipulation off-DOM.

Found via Alex’s blog entry on the dojo page, thanks.

Comments (1)

Dojo migration 0.4 to 0.9, a summary

First things first, if your project allows you to migrate to 0.9 (you got the time to do it) - do it! It’s worth all the sweat and it might cost you some.

I have converted a mid-size project from dojo 0.4 to 0.9 and it took longer than I thought, but also because I had to collect all the info from multiple places, so I will try to share what I discovered or collected and hoepfully make it easier to migrate. Good luck!
If you come across more changes that match somewhere in the list just add them to the comments, I will try to incorporate them.

Namespaces
Some functions have changed their namespaces. Most common functions have moved to dojo.* namespace to simply be quickly reachable. Simply do a console.dir(dojo) on the FireBug console, which lists all the functions that are located in the dojo.* namespace.
I found those changes:

dojo.lang.* => dojo.*
dojo.lang.find => dojo.lang.indexOf
dojo.lang.filter => dojo.filter

dojo.html.* => dojo.*
dojo.html.hasClass => dojo.hasClass
dojo.html.addClass => dojo.addClass
dojo.html.removeClass => dojo.removeClass
dojo.html.toggleClass => dojo.toggleClass

dojo.widget.byId => dijit.byId
dijit.byNode is new, the speeks for itself imho

Some functions disappeared
dojo.lang.isUndefined() disappeared, I didnt find the reasoning anywhere yet. If you have no deeply nested objects you try to check, a function isUndefined() will work well I created one for my project. If you don’t like that I guess you have to replace all calls with typeof varName == "undefined".

dojo.lang.isNumber() disappeared too. My solution:
function isNumeric(v) {return dojo.number.format(v)!==null};.

dojo.html.getPadding() was removed and seems to have become dojo.style(el, "paddingLeft"), dojo.style(el, "paddingRight"), etc. and that looks reasonable, it only gets the data you really need not all the paddings though you would have needed only one.

dojo.html.getScroll() is gone, the hack I use is dojo._docScroll() which does return the data as I need them, but it looks very private :-(.

dojo.dom.removeNode(el) was removed since the same can easily be achieved el.parentNode.removeChild(el), though removeNode() was pretty convinient, but not really necessary. Another intelligent move.

dojo.string.escape() is gone too. I just copied the old 0.4 function (dojo.string.escapeXml() see here for the source) into my local project namespace, I didnt find a replacement in dojo0.9 yet :-(. Probably also a simple thing like the removeNode thing, but I don’t know yet.

Important function changes
dojo.html.toCoordinateObject() was renamed to dojo.coords() which is a good move, since it was way too long. It now returns an object with the keys: w,h,t,l (width, height, top, left). Much more efficient.

this._inherited() is not a function anymore, but I guess I was one of the few who used it directly though I shouldn’t. Now call this.inherited("funcName", arguments).
I think that only due to a bug or missing implementation I used to use _inherited() now it seems to be fixed and as it is supposed to be.
But: inherited() can only be called for the same function as the callee … strange, so we have to use className.functionName.apply(this, arguments) and that is one thing that really sucks, since you hard code the className in the class … I hope that will change.

dojo.fx.html.wipeOut(el, 1000, null, onEnd) changes to this dojo.fx.wipeOut({node:el, duration:1000, easing:null, onEnd:onEnd}).
For all the properties see the dojo._Animation object’s properties are all you can pass to the wipe-method.

Widget stuff
djConfig.searchIds forget about them!
Alex Russel told me in IRC
[12:35] cain: what is the replacement for “djConfig.searchIds” ?
[12:35] slightlyoff: cain: there isn’t one
[12:35] cain: how do i add ids to be rendered as widgets?
[12:35] slightlyoff: cain: there’s only a larger toggle (parseOnLoad)
[12:35] slightlyoff: cain: or you can run the parser yourself on a smaller subtree
[12:35] slightlyoff: cain: but in 0.9, the parser is much much much faster
So all you need to do is put djConfig.parseOnLoad=true at the beginning of your page and all widgets will be found. But be careful you have to manually dojo.require all the widget classes, iirc it was done automatically in 0.4.
The porting guide says:

you must require the Dojo parser along with any widgets referenced, and enable a page scan using the “parseOnLoad” setting

that sucks, for

Comments (3)

Doctests for dojo

Sometimes when you want to do something right and you are lacking the tools you write them (but very often I don’t :-) ), but in the case of doctests for dojo I saw the need. This time I took the time to write a doctest-class for dojo. It is currently only a ticket in the dojo trac, but some feedback looks pretty promising.

I saw the Ian Bicking had already once written a doctest module, but after skimming over it and thinking about the task, I decided to write it from scratch and a pure dojo fit, since it surely is not much work (as it also turned out, which is a rare case).
I knew the doctests module from the Python, where it obviously also comes from. In the beginning I found doctests ugly, those huge chunks of console-pastes inside my docstring. But after getting to know the value of the doctests by learning django’s newforms completely by a huge doctest I felt what they can do and that they can really help a lot.
Doctests just make you understand the code in the place it is written. If you (as I do) often look into the sources it can be really helpful to see a programming example right there inside the docstring of the class/method/function.

To make it short, I implemented this for JavaScript and it works nicely. I am actually developing a dojo.data-store but in order to do that I needed doctests, that’s where the need came from.
One of dojo’s base functions might look like this now:


dojo.trim = function(/*String*/ str){
	// summary: trims whitespaces from both sides of the string
	// description:
	//	This version of trim() was selected for inclusion into the base
	//	due to its compact size and relatively good performance (see Steven Levithan's blog:
	//	http://blog.stevenlevithan.com/archives/faster-trim-javascript).
	//	The fastest but longest version of this function is going to be placed in dojo.string.
	// examples:
	//	>>> dojo.trim(" trim me ")
	//	"trim me"
	//	>>> dojo.trim("\t\ttrim me ")
	//	"trim me"
	//	>>> dojo.trim(" \t\t trim me \t ")
	//	"trim me"
	//	>>> dojo.trim("trim me")
	//	"trim me"
	//	>>> dojo.trim(" trim me")
	//	"trim me"
	//	>>> dojo.trim("trim me ")
	//	"trim me"
	//	>>> dojo.trim("")
	//	""
	return str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');	// String
}

You can see more examples here and here (search for the doctest starting with “>>>” and you will find some).
Below “examples” you can see the inline doctest. I really just wrote those tests in the FireBug console and copied them later into the code.

Run doctests
The trac ticket in dojo including the files and some info you can find here. You can download the patch right here.
First apply the patch, so that the dojox.testing.DocTest module is available.
This patch containing the doctest class is though to be a part of dojo, so it currently requires that you have a dojo module or a module that you registered with dojo (dojo.registerModulePath()).
To run i.e. the above shown doctest you just need to know in which file (module) it is (dojo._base.lang in this case) and type the following into your FireBug console:

>>> dojo.require("");
>>> var doctest = new dojox.testing.DocTest();
>>> doctest.run("dojo._base.lang");

It will then print out a line for each test in the FireBug console with the result and some info. In the before case it looks like this:

...
Test 44: OK: dojo.trim(" trim me ")
Test 45: OK: dojo.trim("\t\ttrim me ")
Test 46: OK: dojo.trim(" \t\t trim me \t ")
Test 47: OK: dojo.trim("trim me")
Test 48: OK: dojo.trim(" trim me")
Test 49: OK: dojo.trim("trim me ")
Test 50: OK: dojo.trim("")

Embed doctest
You can also embed the doctests into other test modules, i.e. if you are just want to add the doctests to your unittests and get them all as one result. You can simply check the property errors of your doctest instance:

>>> doctest.errors
[]

As you can see if there are no errors it’s length is 0.
You can see an example of how to do that here in the file data/tests/stores/QueryReadStore.js the first function testDocTests() runs the doctests of the module “dojox.data.QueryReadStore” and verifies that there are no errors.

I hope this will be useful to some people. Let me know if you have any kind of feedback, bugs or whatever. In the class itself you can see that I have also already thought of some things that need to be done/added to this class. Have fun doctesting …

Comments