Tuesday, June 29, 2010

The RightJS DOM-Wrappers Speed

Okay folks, there is your next brainwashing session to keep you hooked to the right stuff.

When I announced that RightJS is switching to dom-wrappers, some of you seems started to panic. "Oh, no!", you said, "RightJS is going down, because native extensions murk dom-wrappers any day at any time!"

Well people, you just haven't seen the right wrappers yet 8). Here is the shot of the new engine in its raw, not fully optimized state.


FF 3.6.6


And so you didn't think that it's just FF, here is a shot in Opera.


Opera 10.54


Don't have a short for IE though, because didn't quite make it there yet, but you can imagine that it will go sky rocket, because there will be no elements extending anymore.

Some of you, young and sharp, might notice that, the ID access went down for a notch. That's all because of you guys, that's because in RightJS 2, you'll have the same $ method behavior as you have in your beloved jQuery, meaning you'll navigate it like that.
$('#boo-hoo'); // -> an element by id
$('div.boo, div.hoo'); // -> elements by the css-rule

There also will be things like $(window) and $(document), so you'll feel yourself like home.

That's about it. Hold on to the next session!

Saturday, June 26, 2010

RightJS Development Status

Hey folks, to keep in touch, some notes on the RightJS development status.

As you probably already know the next step in the RightJS evolution is coming. Currently I do all the fixes and main feature updates in the 'master' branch and all the dramatic changes go into the 'two.o.o' branch. So if you'd like to see what's going on, go and check it out from github.

So what's actually going on?

New building system

First of all I move the source code building system from the amaturish concatenation of some pieces of code to more serious layouts based builds.

What does it mean?

It's fairly simple. Instead of having all sorts of small isolated pieces of code, now we have one global function which isolates the RightJS initialization process inside. It doesn't mean that RightJS now closes its insides like jQuery does. No, all the crazy monkey patching abilities remain in place and it is still an open architecture, but now we don't need to worry about accidentally polluting the global scope with some temporary variables, plus it gives us a great deal of optimization abilities in speed and size.

Secondly, now we use the google's closure compiler to compact the javascript code. It works a bit faster and provides slightly better results than my FrontCompiler.

I haven't finished yet with all the size optimizations yet, but the layout based builds + google-compiler are already giving us some benefits. Despite that I already added quite a few new features and methods, the size of the builds went down at about 1K and goes like 40K of the minified (not packed) code, which is about 15K in gzip.

Then it seems like I'm going to get rid of the albeit-packed builds. The reason is that most of the web-servers those days use gzip compression and in this case there is no significant difference between the packed and minified versions. And as the packed version initializes slower than the minified one I think there is not much of reasons to continue to support it.

In any case, you'll be able to albeit-pack RightJS with FrontCompiler at any moment by yourself.


The Safe Mode

The are another reason for the layouts based builds - the safe-mode development. And currently there are several directions which the safe-mode development goes.

First of all the name spaced mode. Now as RigthJS initializes inside of a layout, it extends the global scope only at the very end. So you can easily have a name spaced build by removing one line of code from the end of the file and all the RightJS global objects will be available in the scope of the RightJS object.

You still will have all the native and dom object extensions with all the benefits and troubles and your code would look like that

with (RightJS) {
var MyClass = new Class({
include: Options,

initialize: function(id) {
this.element = $(id);
}
}
}

Or, if you're against the with calls, like that

var MyClass = new RightJS.Class({
include: RightJS.Options,

initialize: function(id) {
this.element = RightJS.$(id);
}
}


The second direction is so called condom-mode. The idea is that we initialize RightJS in a separated IFrame and then hook up the main window to the functionality via the RightJS object. In this case you have almost complete isolation of the contexts, RightJS won't touch the main window units and you also will have access to the RightJS fancy native extensions like that.

var R = RightJS;

R('boo.hoo').endsWith('hoo');
R(4).times(...);
R(function() { }).bind(...);
R([1,2,3,4]).without(2,3);
R.$('element-id').onClick(....);

RightJS will extend only those dom-elements which you actually work with. So you'll still have the RightJS speed and easy goingness, but you also have the ability to safely implement say widgets on someones page.

The condom mode is mostly ready, it still has some unfinished parts with the window and document access, but all the other things are already working. you can build and play with it in the `two.o.o` branch like so

rake build OPTIONS=safe



The DOM-Wrappers

The condom-mode is just a step to the next level, it is an interesting thing but it still does extend dom-elements you access. So I'm currently working on the next step which is the dom-wrappers.

The idea is to replace the direct dom-elements access with some artificial proxy which will have all the same interface as a normal dom-element but without actually extending the dom-elements themselves. The reasons are obvious, it's a peaceful coexistence with another scripts on the page and better cross-frame scripting abilities/performance.

This feature is still in progress and you'll see the first results in about couple of weeks.

After that, that's it, we release.


The Summary

One way or another, with the 2.0.0 release we should fix the only problem that wrong with the right javascript framework, the safety. We will have normal quick and naughty builds as we have now, but we also will have options with the namespaced and condom modes.

Which means we will have a rock-solid safety against the anxious MSIE or any other browser that will think its smarter than others, and you also will have the ability to use RightJS to develop widgets in the safe-mode.


That's about it.
Have fun!

Wednesday, June 2, 2010

Postion fixed in IE6

If you old enough you might remember that wonder of technology we used to admire something like ten years ago, which also known those days as the zombi-browser aka IE6. And if you old enough and unlucky enough to have a need to make something with "position:fixed" under that browser, you might think about the usual approach with hooking up the window.scroll event with some piece of javascript and move the thing manually.

My dear friend, there is a better way to hack the shit out of it. Presenting you the CSS hack which will keep your element fixed at the bottom of the window
div.sweet-div {
position: fixed;
bottom: 0;

/* IE6 position:fixed hack */
_position: absolute;
_bottom: none;
_top:expression(eval(document.compatMode && document.compatMode=='CSS1Compat') ? documentElement.scrollTop +(documentElement.clientHeight-this.clientHeight) : document.body.scrollTop+(document.body.clientHeight-this.clientHeight));
}


Enjoy!

Friday, May 21, 2010

Making a Colorpicker

The other day I've been implementing this colorpicker widget for RightJS and now I'd like to share some mathematics and mechanics behind the widget.

I won't bore you to death describing the actual layout, just some necessary theory and math. And I also will use RightJS semantics. Well, just because I love it.

The Color Theory

Lets start with a bit of a theory. Every giggling school girl those days knows that any color can be created by a proper mix of three basic colors, red, green and blue. That's a brilliant idea, but the problem is that not many people actually can use it. Personally me, I don't know anyone who can instantly say how much of every color you need to take to create say a color of coffee and milk.

And because of this problem the humanity created another, more natural way of color picking which is based on another three dimensions: tone, saturation and brightness. And the main idea of the colorpicker widget is to convert one system into another.

The Tone Parameter

The tone picker usually looks like a vertical bar and represents the following system of colors.



The principle is that with this tone scale you can have any tints available with full saturation and brightness. Note also that in every point of the scale, one of the colors is always has a zero value, and at least one of them has the full value.

Keep also in mind that this scale is some sort of closed circle, the end on the right is actually joined with the beginning on the left.

The Saturation And Brightness

The saturation and brightness field usually looks like that.



The saturation parameter is zero at the left side and have the full value on the right. The brightness is full at the top and zero at the bottom. This way, you will always have the white color at the top left corner, your current tint color at the top-right corner and a black line at the bottom side.

With those three handlers you also can chose any visible color but in more natural way.

Converting TSB into RGB

The first task of the colorpicker is to convert the tint, saturation and brightness parameters which the user picks into the actual RGB value.

It was proven that the best way of keeping your values in this case is if you keep your TSB parameters in float values of range 0..1 and RGB values in integers of range 0..255. This way you won't have systematic round up errors and it will be working faster.

So your TSB -> RGB script will look like that
var tint = [1, 0.5, 0];
var saturation = 0.6;
var brightness = 0.4;

var color = [0, 0, 0];

for (var i=0; i < 3; i++) {
color[i] = 1 + saturation * (tint[i] - 1);
color[i] = (color[i] * brightness * 255).round();
}
The principle is simple, first we combine the tint and saturation which will give as a raw color in range 0..1, then we apply the brightness parameter and convert the float value into a 0..255 integer.

Converting RGB into STB

The backward conversion is a bit trickier. I've drown a simple picture to help you understand the principle



Say you have some RGB color with values in range of 0..255. Remember our tint picture, where one value is always 1 and another is always 0. So this smaller area between the green and red values is the same thing, if you take it and normalize to the 0..1 range you'll have your clear tint values. The brightness parameter will be the proportion between the brightest color and the 255 value, and your saturation is relation between the minimal color to the maximum.

The script looks like that
// the initial RGB value
var color = [200, 100, 50];

// finding the minimal and maximal values
var color_sorted = color.clone().sort(function(a,b) { return a-b; });
var max = color_sorted[2];
var min = color_sorted[0];

// calculating the brightness and saturation
var brightness = max / 255;
var saturation = 1 - min / (max || 1);

// calculating the tint
var tint = [0, 0, 0];
for (var i=0; i < 3; i++) {
tint[i] = ((!min && !max) || min == max) ? i == 0 ? 1 : 0 :
(color[i] - min) / (max - min);
}
It is pretty much straight forward, but we also have some failsafe conditions like (max || 1) and (!min && !max) in case if all the RGB values are zeros.


HEX to RGB Conversions

And couple more things which you also will need. Converting your 0..255 colors array into HEX and RGB formatted strings back and forth.

Converting an array to a HEX value is simple
'#'+ color.map(function(c) {
return (c < 16 ? '0' : '') + c.toString(16);
}).join('');

Converting RGB string into an array of values looks like that
if (match = /rgb\((\d+),(\d+),(\d+)\)/.exec(value)) {
return [match[1], match[2], match[3]].map('toInt');
}

And converting any HEX color into an array can be done like that
// converting the shortified hex in to the full-length version
if (match = /^#([\da-f])([\da-f])([\da-f])$/.exec(value))
value = '#'+match[1]+match[1]+match[2]+match[2]+match[3]+match[3];

if (match = /#([\da-f]{2})([\da-f]{2})([\da-f]{2})/.exec(value)) {
return [match[1], match[2], match[3]].map('toInt', 16);
}

Well, that all you need to know to make one cool colorpicker of yours.
Enjoy!

Tuesday, May 18, 2010

Automatic Records Search in Rails

There is one neat trick I'd like to share. In many cases, especially when you work on intranet applications, you need say to check some security settings against the data-records before you let the request to access the actual method in your controller. Normally, most folks do that by adding before filters to find the records, like that

before_filter :find_this
before_filter :find_that

def find_this
def find_that

When your application grows and starts having something like a dozen models, plus you might have nested routes where you need to check the security against the nested elements too, those things tend to get really messy.

So here is a simple method which I use on my projects

before_filter :find_restful_units
def find_restful_units
params.each do |key, value|
if key == 'id' || key.ends_with?('_id')
unit_name = key == 'id' ? controller_name.singularize : key.gsub('_id', '')
unit_class = Object.const_get(unit_name.camelize)
instance_variable_set("@#{unit_name}", unit_class.find(params[key]))
end
end

rescue NameError # just hung up if there is no such unit
nil
end

You put this in your ApplicationController and it will automatically find and assign all your models, the actual and the nested ones.

This makes controllers much cleaner and you always have your models extracted and ready to use in the standard way.

Wednesday, April 28, 2010

RightJS vs. MooTools In The Game of Mines

This weekend I had some fun implementing the good old game of mines using RightJS. The result is pretty cute, you should check it out. No, really, you will like it.

The thing is that about year and a half ago I implemented the same exact game using MooTools, you can check it out over here, and well, I have some words to say on this regard.

Okay, I certainly did get better during this last year and you might say that I know RightJS better than MooTools, but here are some numbers. (For the sake of a clean experiment I specifically didn't look into the old code before or during the development and eventually gone in a different approach in the implementation.)

With MooTools I was working on the game almost the whole week, I didn't work full time and as I recall it you could say it were good three, three and a half days of work. The result is 14k build of JavaScript + about 5k of CSS, which is about 19k in total.

In case of RightJS it took me about 6 hours to implement the whole thing from top to bottom, and the result built of JavaScript + CSS is just 9K of code.

Yup, a twice as compact result and about four times less time spent. More of that I believe that RightJS implementation has much cleaner and easy to understand code.

The really sweet things in case of RightJS were the number extensions, simplified collections processing and built in Observer unit. It feels so good and natural to implement game logic with them! I really enjoyed those things!

Well, that's about it.

Monday, March 29, 2010

RightJS + Rails = Love

As the right-rails (the Ruby On Rails plugin for RightJS) was updated recently, lets have another brainwashing session. This time for Rails people.

If you're a kind of a pragmatic developer, you're probably asking yourself "why would I fall in love with this new thing? I already know Prototype and jQuery why would I need something else?", and believe me, I know precisely what you mean.

But ask yourself, being a Rails developer, were you ever happy of doing AJAX features in Rails? No, I mean, not like first two weeks on rails, or things like "it's working". I mean really happy, did you feel funny about Prototype or jQuery? Did they make the butterflies in your stomach fly? Literally.

Think about it. The Prototype support on Rails was always a kind of a flimsy hack and most serious developers don't really use those RJS stuff. And with jQuery you were always left alone to deal with all those kinky JavaScript stuff. That's good if you are a JavaScript guru and know your magic. But what if you are not, and what about the actual Rails business anyway? Did any of the frameworks really helped you in any way to be an actual Ruby/Rails developer?


How Is RightJS Different?

First and most important thing you should know about RightJS is that it was written by a Ruby/Rails developer for Ruby/Rails developers. And despite the fact that from time to time we have all those arrogant promotions and we mock jQuery folks constantly. RightJS is not really about JavaScript itself. It is something quite opposite.

RightJS is all about getting JavaScript off your hair. RightJS is made to help Ruby developers to deal with JavaScript tasks, it reflects Ruby way of handling things, has mostly Ruby syntax and many of its key features are copies of Rails features.

RightJS civilizes JavaScript and brings it closer to Ruby developers.

But we didn't came here to talk about JavaScript, right? What about Rails itself?


Lets Make The Butter Fly

How much time does it take to make a date-time field with a calendar in your framework?

Let me spare you the calculations time and show how it looks like in RightJS + RightRails.

<% form_for(@zing) do |f| %>

<%= f.calendar_field :dead_line %>

<% end %>

Nope. I didn't forget nothing. `calendar_field` is all what it takes. RightRails automatically includes all necessary JavaScript, CSS and I18n modules on your page and initializes the fields, so you don't need to worry about a thing.

More of that, it will automatically swap between builds and source code for JavaScript in production and development modes.

So, would you like some rater or slider on your form?

<%= f.rater_field :rating %>
<%= f.slider_field :completeness %>

Oh, I know! You'd like some autocompleter, right?

<%= f.autocomplete_field :category, :url => categories_path %>

Would you like the autocompleter to be RESTful design and hard-caching friendly? No problem!

<%= f.autocomplete_field :category, :url => "/categories/%{search}.js" %>

Here you go.


And That's Not All

The fun is not over, not by a long shot. The next feature is that RightRails comes with a brand new RJS generator, and that's not just a collection of dummy functions like in the case of the Rails original RJS templates.

The new generator lets you literally write JavaScript in Ruby and more of that it allows you to mix Ruby and JavaScript calls in one flow escaping and transforming variables on fly.

For example this is how the annoying nested forms look like when you make them with RightRails.

<% form_for(@zing) do |f| >

<div id="categories">
<%= render @zing.categories %>
</div>

<%= link_to_function 'add' {|page|
page[:categories].insert(render(Category.new))
} %>

<% end %>

See, the `insert` method is a JavaScript function, the `render` is the ActiveView method, `Category` is your model. All in one flow with automatic types conversion. And it is not just a list of predefined functions, you can literally do whatever you want.

update_page do |page|
page[:todos].update render(@todos)

page[:todos_count].innerHTML = @todos.size + ' Items'

page[:todos].select('li').each do |item|
item.onClick('toggleClass', 'marked')
end

page.json_variable = @todos.to_json
page.items_count = @todos.size
page.list_updated = true

page.alert "There are #{@todos.size} items left on the list"
end

There are no limiatations.

Mommy Look, More Fancy Stuff!

Oh yes mommy, there are! On top of all RightRails has a conventional interface to cover the most common AJAX CRUD operations. Let me show you.

Say here's your remote form

<% remote_form_for(@zing) do |f| %>

<%= f.text_field :name %>
<%= f.file_field :picture %>

<%= f.submit 'Create' %>
<%= image_tag 'spinner.gif', :class => :spinner %>

<% end %>

And here is your controller method

dev create
@zing = Zing.new(params[:zing])
if @zing.save
render rjs.insert(@zing)
else
render rjs.replace_form_for(@zing)
end
end

The `rjs` method provides access to the new RJS generator from the controllers, and `insert` and `replace_form_for` are the AJAX operations interface.

It all works over the Rails conventions, the `insert` method looks for the class of the `@zing` model, finds related partial, renders it and generates a piece of JavaScript that inserts the HTML into an element with the `zings` ID.

The `replace_form_for` method will render a new form with all the error messages for the @zing model and generate JavaScript that will update the form on the page.

RightRails has a collection of such methods for all CRUD operations.

Note also that I've put a file field and a spinner image on the form. RightRails automatically and transparently processes files uploading too, basically there is no difference whether your form has files or not, it all has the same API. And the RightJS when submits a form via AJAX, automatically searches for images with the `spinner` class and uses them as spinners, you don't need to hook them up with callbacks manually.

Summary

I'm not going to indulge you with obvious conclusions, I'll just tell you that I've already used RightJS + RightRails on two production projects and it saved me hell of a lot of time and nerves on JavaScript and AJAX development.

Well, it was designed to.