Saturday, July 31, 2010

RightJS 2.0.0-rc Is Out

Okay folks, RightJS 2 came to the point where it has a proper number and the '-rc' suffix in it's name. And here are some notes on the new sweet features we have since the beta release.

You can download the build over here, the archive contains both normal and safe-mode builds.

Generally this is almost the final line, I've finished packing it with new features and this is practically all we will have in the actual 2.0.0 release. There might be some tweaks here and there during the plugins and UI modules porting, but nothing dramatic. So lets check what we've got.


Dom Wrappers

In RightJS 2.0 we have a new kick-ass object oriented dom-wrappers system. Our dom-wrappers are essentially classes, with types, inheritance and all the nice functionality injection features. Currently we have the following wrappers Window, Document, Event, Element, Form and Input, which formerly was known as the Form.Element unit.

Dom-wrappers work transparently and have all the same nice API we had in RightJS 1, the only difference is that instead of the actual dom-element all the methods now operate with dom-wrappers.

$('element-id')  // -> dom wrapper
$$('#css .rule') // -> a list of dom-wrappers

All the dom wrappers are inherited from the same unit called `Wrapper` and have a common property called `_` which refers to the raw dom element, for example

$('element-id')   // -> Element wrapper
$('element-id')._ // -> the actual dom-node

$(window) // -> Window wrapper
$(window)._ // -> the window object

$(document) // -> Document wrapper
$(document)._ // -> the document object

So every time when you fill like it, you can always quickly access to the raw unit the same way across all the wrappers.


Dom-Wrappers Typecasting

As you might noticed we have three types of wrappers for dom-elements, the Form and Input classes are subclasses of the Element class and when you access your dom-elements they dynamically typecasted

var element = $('my-form');
element instanceof Element; // -> true
element instanceof Form; // -> true
element instanceof Input; // -> false

var element = $('my-input');
element instanceof Element; // -> true
element instanceof Input; // -> true
element instanceof Form; // -> false

This way you can check which type of element do you have and you can extend all of them separately


Element.include({
global_method: function() {}
});

Form.include({
forms_only_method: function() {}
});

Input.include({
inputs_only_method: function() {}
});

You even can use polymorphism and use the same method names

And you also can define your own types, for example

Element.Wrappers.TABLE = new Wrapper(Element, {
orderBy: function() {}
});

Later on there will be also private dom-wrappers which you can use in your app without extending the RightJS core and interfere with other applications.


Bubbling Dom-Events

RightJS also received several fixes for the traditionally problematic dom-events like focus, blur, change and submit, now all of them properly bubble on all the supported browsers.

There is nothing kinky about it I didn't use any special event names, just use the usual ones like nothing happened.

$(element).on({
focus: ...,
blur: ...,
change: ...,
submit: ...
});

I also added the custom events bubbling. If in RightJS the custom events didn't go anywhere from the node where you fired it, now they properly bubble up to the document object, so you can take advantage of them using the events-delegation technique.

Speaking of which.


New Events Delegation API

In the later releases of RightJS 1.5 we already had some elements of the events-delegation feature support, now it's time to take it to the next level.

First of all the String unit now has all the same API as Element, so you don't need to learn nothing new, just use what you already know.

"#div .span".on('click', function() {...});
"#div .span".onClick(function() {});
"#div .span".onClick('addClass', 'marked');

// you also can make the normal checks
"#div .span".observes('click'); -> true
"#div .span".observes('mouseover'); -> false

// and you can unbind the listeners the usual way
"#div .span".stopObserving('click', function() {});

Then the Event.delegate and Event.behave methods are gone and instead of them we have a proper events delegation API on dom-wrappers which look like that

$(document).delegate('click', '#css.rule', function() {});
$(document).delegate('click', {
'#css.rule1': function() {},
'#css.rule2': function() {}
....
});

// delegation checks
$(document).delegates('click');
$(document).delegates('click', '#css.rule');

// disabling delegation
$(document).undelegate('click');
$(document).undelegate('click', '#css.rule');

More of that the same API was adde to the Element wrapper so you can attach your delegating listeners at any level of your web-page

$('my-list').delegate('click', {
'li.one-thing': function() {}
'li.another': function() {}
});

This way you can scope the delegation to some block of your document and handle the things locally.

You also can delegate custom events too

$(document).delegate('bingo', {
'#one': function() {}
'#another': function() {}
});

$('one').fire('bingo');
$('another').fire('bingo');

Generally there are no limitations and you handle any sort of events simultaneously via the same api.


$$ Is Back!

As you might noticed I moved the $$ function back. I tried to use the jQuery-like unified $ method but didn't like it and brought the $$ back.

Amen.


Semi-Safe Mode

As you might know RightJS 2.0 will have the safe-mode build, which will hide everything behind a single RightJS object and won't extend a thing on the user's page.

A typical use case would look like that

RightJS.$('element-id').onClick(....);

var MyClass = new RightJS.Class({
...
});

There is also a way to access the language unit extensions by passing variables through the RightJS object

RightJS(['boo', 'hoo', 'doh']).filter('includes', 'oo');
RightJS(4).times(function() { .... });
RightJS('boo hoo').endsWith('hoo');

In the RC release I added a semi-safe API for the non-safe builds, meaning you can put your variables through and access the RightJS units via the RightJS object. This way if you need say to write a plugin that supposed to be working in both safe and non-safe modes, you can simply write it for the safe-mode and it will be working in the non-safe mode too.


JSONP Support

In RightJS 2.0 there is the JSONP format support for the Xhr unit. It all works transparently via the same Xhr API with all the same principles, the only thing is that now you have the jsonp option where you can specify your callback name variable, or simply use true for the default 'callback' value.

new Xhr('/some/url', {
jsonp: 'myCallback',
onSuccess: function() {
// ....
}
}).send();

Xhr.load('/some/url', {jsonp: true});

It even will assign the responseJSON and json varaibles

Xhr.load('/some/url', {
jsonp: true,
onSuccess: function() {
console.log(this.json);
}
});



New Language Level Methods

There are also several new javascript level extensions were added. Object.each, Array#reject (which is useful with calls by name), Array#min, Array#max, Array#sum

Probably something else that I have forgotten.



The Next Steps

Now when the core is finished, there are quite a lot of work with porting the plugins to the new version and reworking the documentation. The site also needs to be reworked to support the new building system.

At the moment I estimate it like 2-3 weeks of work. So the delivery-day is somewhere by the end of summer.

Okay, think that's all I have for know.
Take care!

Friday, July 30, 2010

Why Albeit Packing Is A Bad Idea

Okay I did it quite a lot on RightJS, but I've learned my lesson. A quick and self-explanatory example would be like that.

Say you have the following piece of javascript

a1.looooongMethod();
a2.looooongMethod();
a3.looooongMethod();
a4.looooongMethod();
a5.looooongMethod();

Being an optimization junky, you might think, "Oh! I can make it smaller!"

var b = 'looooongMethod';
a1[b]();
a2[b]();
a3[b]();
a4[b]();
a5[b]();

Then you look at the size, the first one weights 104 bytes and the second one 70.

"Woohoo!", you say, "30% optimization!". And will be wrong.

Because when a web-server gzips your code, the first one will weight 61 bytes and your optimized version will be... TADA! 72 bytes. Yup, bigger than it was before 8)

That's the whole story. Gonna go and unoptimize things back now.

Monday, July 19, 2010

Freezing Terminal.app in OS X

I ran in a strange bug yesterday on my macbook. Suddenly the Terminal.app started to freeze when you lunch it or open another window.

I killed half a day trying to figure out what's wrong with my HDD, and trying to restore parts of the system from a backup, but then found out that the problem was in another place.

So if you run into the same issue the cure is simple.
sudo rm -rf /private/var/log/asl/*

Apparently there is some problem with the log files that cause circular read/write calls, so when you nuke the old logs, it will get just fine