My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

Thursday, March 13, 2008

ABC - Ajax Basic Call

I know everyone uses incredibly cool libraries that do everything in few lines, and 30 or more Kb ... but do you always need all this stuff for simple Ajax interactions?

The JavaScript ninja secret is to create everything ad hoc, where everything will be under control and will be extremely optimized and, why not, fast.

ABC goals is to let you use, simply, Ajax.

What is Ajax in few words? The possibility to send and recieve data, usually using GET, POST, or both method (POST with a query stirng).

That's exactly what you can do with ABC, and these are major features:

  • simple, fast, lightweight ... probably the only function you need for 80% of Ajax tasks

  • unobtrusive, does not change, create, modify ... absolutely nothing

  • IE cache safe, forget IE cache problems without effort

  • array compatible, send single dimensional arrays too

  • easily integrable, using around your own cool code to send entire forms or whatever you need

  • quick but not dirty, and without global scope paranoia ... one function, every number of interactions you want, syncronous or asyncronous



Here some example code:

// basic asyncronous GET request
ABC(null, "page.php?hello=ABC");

// basic asyncronous POST request
ABC({hello:"ABC"}, "page.php");

// basic syncronous GET request
alert(
ABC(null, "page.php?hello=ABC", false).responseText
);

// basic syncronous POST request
alert(
ABC({hello:"ABC"}, "page.php", false).responseText
);

// basic syncronous POST with GET request
alert(
ABC({hello:"ABC"}, "page.php?query=string", false).responseText
);

These are only the beginning ... there's more, because we all love callbacks and asyncronous requests!

ABC({
parameter1:"Hello",
parameter2:"World",
list:[1,2,3,4,5],
onLoad:function(xhr, elapsedTime){
alert([elapsedTime, xhr.responseText]);
}
});

ABC({
parameter1:"Hello",
parameter2:"World",
list:[1,2,3,4,5],
onLoad:function(xhr, elapsedTime){
alert([elapsedTime, xhr.responseText]);
},
onError:function(xhr, elapsedTime){
alert([elapsedTime, xhr.status]);
}
});


Both onLoad and onError are optional callbacks ... and that's basically how ABC works to choose GET or POST method:

  1. If first argument is null, or it does not contain object properties that are not functions, the request is GET

  2. If first argument contains an object with at least one parameter that is not an Object prototype and is not a function, the request is POST

  3. If third arguments is not present or is undefined, request is syncronous by default

  4. If third arguments is true or false like (1, 0, "ok", undefined or null), the request will be asyncronous if true, syncronous if false (basic XMLHttpRequest behaviour)
  5. If you pass fourth and/or fifth argument, these are user and pass



The good thing is that you have exactly same parameters that a regular XMLHttpRequest instance wants in open methods. This basically means that migration between some code will be ridiculously simple.

On the other hand, ABC is simple and is perfect for simple things.
Of course if you need more features ... you are higher level than ABC ... but for every other client / server interaction, are you sure you need every time so many features?

This is the source, and this is the packed.it version ... about 0.66Kb (deflate) ... and that's it! Enjoy Ajax :geek:

Wednesday, March 12, 2008

Do You Like Browser Benchmarks? Here I am!

Hi guys,
today we will not talk about my last JavaScript ArrayObject creation :D

Today is the benchmark day, and in this case the test is as simple as explicative ... both Math object and scope are two things we use every day for whatever purpose in this baby Web 2.0 era!

Let me start directly with results (ORDER BY speed ASC):

Firefox 3.0b4
----------------------------------
regular avg time in ms: 9.98
scoped avg time in ms: 3.18
encapsulated avg time in ms: 12.98


Safari 3.0.4 (523.15)
----------------------------------
regular avg time in ms: 13.42
scoped avg time in ms: 6.42
encapsulated avg time in ms: 11.82


Opera 9.24
----------------------------------
regular avg time in ms: 13.82
scoped avg time in ms: 9.6
encapsulated avg time in ms: 17.64


Internet Explorer 8.0.6001.17184
----------------------------------
regular avg time in ms: 16.42
scoped avg time in ms: 6.82
encapsulated avg time in ms: 16.82


Firefox 2.0.0.12
----------------------------------
regular avg time in ms: 26.84
scoped avg time in ms: 42.06
encapsulated avg time in ms: 28.64


What kind of benchmark is it?

This is a double test that includes the usage of scoped shortcuts, and the usage of the object that you cannot absolutely get by without: the global Math one!

To understand better this kind of test, please look at these functions:

function regular(){
for(var i = 0, time = new Date; i < 10000; i++)
Math.round(i / Math.PI);
time = new Date - time;
return time;
};

function scoped(){
for(var round = Math.round, PI = Math.PI, i = 0, time = new Date; i < 10000; i++)
round(i / PI);
time = new Date - time;
return time;
};

function encapsulated(){
with(Math){
for(var i = 0, time = new Date; i < 10000; i++)
round(i / PI);
time = new Date - time;
};
return time;
};


The first one, is the most common in every day libraries / scripts, while the second one and the third one, are used by "a little bit more skilled" developers.

The second one, uses the same concept of my good old friend, the smallest FX library from 2006: bytefx

The scoped schortcut is absolutely the fastest way to use a global objet, constructor, whatever you want.

Just think about nested scopes, this amazing ECMAScript 3rd Edition more close to future than many other new program languages ... ( IMO, and sorry for exaggeration :lol: )

When you write the name of something in your scope, the engine looks obviously in the same scope, than in the external one, going on until the super global object, the window

This behavior is basically what should happen using the with statement as well ... but unfortunately, even if this is basically what's up, performances are clearly against the usage of absolutely comfortable with statement.

At the same time, there is one browser that you are probably using right now, that create a bit of confusion about everything I've just said right now: Firefox 2

With quite twice of time, using scoped shortcuts, this browser (the best I've ever used for years, and the one I'll use for other many years) reverse totally my conviction about how does scope work ... anyway, we are lucky because Mozilla staff is creating good stuff with Firefox 3 ... who cares about Firebird and other old versions? :D

Don't you really trust me and my results?
So do this bench by yourself :geek:

Tuesday, March 11, 2008

Sorry Dean, I subclassed Array again

Most library authors would love to extend the Array object (especially for those tasty iteration methods) but shy away from doing so for fear of breaking other scripts. So nearly all (with the noteable exception of Prototype) leave Array and other built-in objects alone.

This is how Dean Edwards started one of his (historic) post about subclassing Array, but I finally found the way to do it better, and You'll read why and how ... please be patience :D

The nightmare does not come only from IE


We all know how weird is Internet Explorer when you try to use an array as a constructor prototype.
What you probably do not know yet, is that IE is the only one that gives you problem "instantly instead of during". Let's start with the first, basic example:

// FireFox and Safari, plus IE, why not

function MyArray(){};
MyArray.prototype = [];

/** this should be a must ... however, who cares about that ...
MyArray.prototype.constructor = MyArray;
*/

var ma = new MyArray;
ma.push(1,2,3);
alert(ma); // 1,2,3 ... seems good, isn't it?

// now, lets use our Array thinking it's an array
var a = new Array(4,5,6);

// now, for some reson you should use your
// personal Array as is ... an Array, are you sure?
a.push.apply(a, ma);

/*
second arguments to Function.prototype.apply
must be an array

expected object or arguments

type error ...
*/

Well done ... we cannot use an instance that inherits from Array as an Array. The only one that seems to be clever enough to understand that ma is basically an Array, is Opera, well done Opera Team!.

The unespected instance


Another weird situation, using precedent constructor as example, is this one:

// Every browser you can try ...

function MyArray(){};
MyArray.prototype = [];

var ma = new MyArray;
alert(ma.concat(ma) instanceof MyArray); // false

false ??? ... What does it mean, false ?
False means that if we should be able to subclass an Array with IE too, there's no browser so clever to understand that internal methods should create an instance of the same constructor ... ok, ok, it's more close to ED209 in Delta City than reality ... anyway ...

I would like to obtain an instance of my constructor, and not an array.
This simply because we could extends whatever we want and after we use every native method, so fast and so powerful, we basically will lose our enhanced constructor coming back to a native Array.

In few words, if we should be able to extend Array, we should create wrappers for every method that returns, natively, an Array ... who talk about performances?
Just think that every this.slice() inside our prototypes should convert again the result if we would like to threat them as an instance of our super extended Array. ... does it sound still cool?
map, filter, sort, reverse ... and many others!

A clever solution, that noone seems to like so much


Basically, Dean found a solution that's clever and simple at the same time.
This one has not been used so much by libraries developers ... but why?
What I could suppose, is that there are a lot of limits:

  1. it depends on iframe creation, while JavaScript could be used everywhere, not only when an element is ready to recieve an iframe inside

  2. an iframe could means a lot of problems, specially in https sites, where some browser (of course IE) has a sort of paranoia if the iframe does not contain an src that points to a file in the same domain ... and sometime, even an empty html file to use as sentinel for empty iframes could be boring ...

  3. the iframe solution, has the same problem than Array extension ... if you want more power with native methods too, you have to wrap them!



Here is an example:

// directly from Dean Edward page
onload = function(){
var iframe = document.createElement("iframe");
iframe.style.display = "none";
document.body.appendChild(iframe);
frames[frames.length - 1].document.write(
"<script>parent.Array2 = Array;<\/script>"
);

// let's play
var a = new Array2(1,2,3);
alert(a); // 1,2,3 ... Yes!
alert(a.concat([4,5,6]) instanceof Array2); // FALSE AGAIN!!!
}


bloody hell, why the native concat method of my Array2 constructor returns an Array?

No way, if You use a native prototype, its behavior will be the expected one for current enviroment ... so as new Array ported inside the iframe will generate an instance of Array2 for every method that returns a partial or full copy of the Array.

More light in the black hole, please


Even if I agree with Dean when He says

shy away from doing so for fear of breaking other scripts. So nearly all (with the noteable exception of Prototype) leave Array and other built-in objects alone.

(removing the notable exception) ... I think that sometime prototypes could save our work, avoiding huge brainstormings to find alternative solution.

Array.prototype.to


Exactly, a stupid, short, simple, damned Array.prototype that has this goal:
Transform an Array like instance into a generic Array like instance (does it sound redundant?).

Array.prototype.to = function(constructor){
if(this instanceof constructor)
return this;
var self = new constructor;
Array.prototype.push.apply(self, Array.prototype.slice.call(this, 0));
return self;
};

This prototype could solve every kind of Array like transformation problems.

Do You need a jQuery from an Array ?

[document.body, document.getElementById("test")].to(jQuery).each(
function(element){
// do whatever stuff
});

You can use this stupid prototype to transform your results as well, but basically, you can use this prototype for every kind of Array like object.

jQuery.prototype.to = Array.prototype.to;
jQuery("input").to(Array).sort(function(el1, el2){
return el1.value < el2.value ? -1 : 1;
}).to(jQuery).doStuff();

Performances are really good, and compatibility is excellent. Starting from IE 5.5 and more, adding your own little simple push prototype plus a Function.prototype.call ... and you'll have support for IE4 too, even if this will not do make sense!

I know that a prototype to a global native variable is never a good thing to assing, but:

  1. Array or Array like objects (arguments) are often (always?) looped using their length and not using for in

  2. if you want to add aprototype, why do not add one that is strictly related with the same constructor and cosntructor like objects?



ArrayObject, and my last call for a truly subclassed Array


Thanks to precedent idea, the Array.prototype.to, I totally redraw my ArrayObject, now compatible with quite every JavaScript 1.6 method without other dependencies, and finally extendible in the most simple possible way, to create your own Array like library. Do you want an example?

// first of all, your constructor
function MyArrayLikeLib(){
// be sure that basic behavior is Array like
// using ArrayObject constructor
ArrayObject.apply(this, arguments);
};

// extend your constructor with an ArrayObject instance
MyArrayLikeLib.prototype = new ArrayObject;

// finally, add one or more prototypes to your personal
// constructor ... but DO NOT FORGET the constructor!
MyArrayLikeLib.prototype.constructor = MyArrayLikeLib;


var demo = new MyArrayLikeLib(1,2,3);
alert(demo); // 1,2,3
alert(demo.concat(new MyArrayLikeLib(4,5,6))); // 1,2,3,4,5,6
alert(demo.concat(new MyArrayLikeLib(4,5,6)) instanceof ArrayObject); // TRUE
alert(demo.concat(new MyArrayLikeLib(4,5,6)) instanceof MyArrayLikeLib); // TRUE


Thanks to the to prototype, natively created in the ArrayObject itself, you will recieve for every method that returns an array like object, an instance of your constructor.

How can it be possible?

// one ArrayObject prototype method, the slice one
slice: function(){
return Array.prototype.slice.apply(this, arguments).to(this.constructor);
}

It's diabolic simple if you remember to assign the real constructor to the prototype!

How to add prototype methods to ArrayObject inherited constructor


Uhm ... this is quite a newbie question, isn't it? :lol:
However, just forget the new Object assignment, or use the object in a different way:

function A(){ArrayObject.apply(this, arguments)};
A.prototype = new ArrayObject;
A.prototype.constructor = A;
(function(prototype){
for(var key in prototype)
A.prototype[key] = prototype[key];
})({
doMyStuff:function(stuff){
this.push(stuff);
return this.sort();
},
each:function(callback){
this.foreach(callback, this);
}
});


A simple benchmark


This page contains some simple speed challenge between native Array and ArrayObject.
Of course in some case ArrayObject is a bit slower, specially with Safari beta for widnows, but those are the worst case scenario, where for compatibility and unexpected behaviors reason I had to put more code, while every, forEach, indexOf, join, lastIndexOf, pop, push, reverse, shift, and finally some, are native when your browser is cool, are compatible and fast enough, when your browser is IE.

The bad news, what You cannot do with ArrayObject


You know, arguments is exactely an ArrayObject like variable ... and what's up if you do something like this?

function length(){
for(var i = 0; i < 3; i++)
arguments[arguments.length] = i;
alert(arguments[0]); // 2
alert(arguments[1]); // undefined
};

length();

You cannot use the length as a getted/setted property as is for native Arrays, but hey, you have native push method, why should you use the length in that way?
(speed? ... if you think that will boost up your applications, use native Arrays inside those loops, and finally convert them.to(ArrayObject)) ;)

Kind Regards


P.S. just another tricky usage of Array.prototype.to

function args2arr(){
arguments.to = [].to;
return arguments.to(Array);
};
alert(args2arr(1,2,3)); // 1,2,3

Thursday, March 06, 2008

Jaxer and packed.it ... not possible yet

Unfortunately, my experience with Jaxer has been really cool but this project is too young to be used as a server side project, and this is only my opinion.

First of all, the simple File API is great, but if you look for binary safe in the search form, you'll be redirect in an empty page ... quite hilarious, isn't it?!

Anyway, I did not test the file.open("wb") mode, probably it's working, probably not ... who care about that? Me, because to pre compile packed.it projects using MyMin and then Zlib I need to write in binary mode ... no way guys!

At the same time, there's not a true bridge for Java, at least that what I was looking for, since Jaxer could be integrated with TomCat, I wonder what are they waiting for to create an easy interface to call directly Java, or whatever mature server language you want.

It will be an extreme start up improvement for your project, what's not possible yet, will be with some Java, Mono, Python, Ruby, PHP, or whatever is it, wrapper.

Is this in your roadmap? None, I can read about DRW but come on guys, the server before the client!

You can have the best Ajax based solution on client, but if the server could do things that a basic PHP / JS interaction could do since 2000 or before, I wonder why you are putting so much effort on client side, where we have a lot of choice, while what we do not have, is simply Jaxer, but on server ;)

Finally, good stuff, and good project, I wish you all the best but please, think about Ajax after a good bridge ... and of course, I eat JavaScript in the morning and I compile them during the night :lol: ... are you still looking for a JS ninja ?

Enjoy Jaxer, at least for fun, this project will become awesome the day it will integrate JS2 engine!


P.S. I created a parseIni method as well ... this is not probably perfect but hey, about 20 minutes debug included :geek:

MyMin = {Creator:function(){}};
MyMin.Creator.prototype.parseValue = function(value){
var result;
switch(true){
case value instanceof Array:
result = [];
for(var i = 0, length = value.length; i < length; i++)
result[i] = this.parseValue(value[i]);
break;
case /^true$/i.test(value):
result = true;
break;
case /^false$/i.test(value):
result = false;
break;
case /^[0-9]+$/i.test(value):
result = parseInt(value);
break;
case /^[0-9]*\.[0-9]+$/i.test(value):
result = parseFloat(value);
break;
default:
result = value;
break;
};
return result;
};
MyMin.Creator.prototype.parseIni = function(fileContent){
var self = this,
pos = 0,
result = {},
trim = /^\s+|\s+$/g,
section,
name,
value;
while(pos < fileContent.length){
pos = fileContent.indexOf("[");
if(pos < 0)
break;
fileContent = fileContent.substr(++pos);
pos = fileContent.indexOf("]");
if(pos < 0)
break;
section = fileContent.substr(0, pos++);
if(!section)
continue;
fileContent = fileContent.substr(pos);
pos = 0;
result[section] = {};
fileContent.replace(/(\[.+\]|.+=[^;\n\r]+)/gm, function(match, sub, p){
if(pos === 0 && /^\[.+\]/.test(match))
pos = p;
else if(pos === 0){
value = match.split("=");
name = value[0].replace(trim, "");
if(/\]$/.test(name)){
name = name.substr(0, name.indexOf("["));
if(!result[section][name])
result[section][name] = [];
result[section][name].push(self.parseValue(value[1].replace(trim, "")));
}
else
result[section][name] = self.parseValue(value[1].replace(trim, ""));
}
});
fileContent = fileContent.substr(pos);
pos = 0;
};
return result;
};

Wednesday, March 05, 2008

Turbo ArrayObject

Today I am more clever than two days ago :lol: ... that's why ArrayObject has now a turbo compressor, specially with those methods that do not require an intermediate wrapper:

  • every

  • forEach

  • indexOf

  • join

  • lastIndexOf

  • pop

  • push

  • reverse

  • shift

  • some



These methods, if susported (if not use JSLRevision ;)), works directly in core.
The result is that every Array like instance now are more fast than ever, considering that join, pop, push, reverse, indexOf, shift, and forEach are widely used in a lot of projects.

This object could be the core for libraries like jQuery, or other that emulates array behaviour ... and I solved problems with sort plus some minor fix.

It has been successfully tested in FireFox, IE, Safari, and Opera.

Seems cool? I hope so :geek:

Sunday, March 02, 2008

JavaScript ArrayObject

I think this constructor could be a good start point for a lot of projects.

We know that IE has problems while it try to extend an array, disabling length modification.

That's why I have created this wrapper that does not require weird strategies (e.g. iframe with a different enviroment) and works with a wide range of browsers.

Honestly, I did not test performances against pure arrays, but I did everything to make code as fast as possible, using good practices and creating an in-scope shortcut for the Array.prototype.

Have a look here if you are interested in this constructor, ignore them if you do not think this is a good idea :)

P.S. Please note that this constructor does not care about missed prototypes, it only does its wrapping work and nothing else. To improve Array compatibility and methods, please remember my JSL Revision. Including them in your page, You'll not have problems with every ArrayObject method, eccept for reduce and reduceRight (I will create a good implementation of those function, I promise!)

Saturday, March 01, 2008

[COW] The fastest JavaScript rand ... isn't it ?

Hi guys, the WebReflection COW is a function that's so simple as usual: the php like rand function, to create random number, or random boolean evaluation:

function rand(min, max){
return max ? min + rand(max - min) : Math.random() * ++min << .5;
};

// pseudo packed version, 62 bytes
function rand(m,M){return M?m+rand(M-m):Math.random()*++m<<.5}


What's new? Nothing, but could be useful :lol: ... and it has really good performances

// boolean evaluation
var testMe = rand(1) ? true : false;

Above example is for boolean assignment for random things
The function works as PHP one, creation of something casual apart.
I mean, if you use rand(), why don't you use Math.random() ?
So, basically, this function is to have a random number from 0 to N, where N is the min argument, or from min to max, where MAX is the second one.

rand(2); // 0, 1 or 2
rand(2, 5); // 2, 3, 4 or 5

Have a nice WE

Wednesday, February 27, 2008

[ES4] ... too horrible to be an editor ...

... but probably simple enough for these milestones.

Its name is ES4me, it's for windows and works in this way:

  • download the file in your es4 folder, where there is the run.exe and the es4.bat file

  • double click



Basically, there is a place to write something, where for some reason TABS are usable only with CTRL + TAB instead of single TAB key, a panel where errors or output will be showed, and finally, 5 buttons:

  • Run, to execute the code

  • Clear, to clear the code in the area

  • Add Before, to add area code before execution

  • Get Before, to add in area the code added before

  • Clear Before, to clear content added before



Here some example:

var i:int = 123;
print(i);

Press Run, and You'll read 123 on output panel.
Now press clear, and area will be without text.
Write again ...

var i:int = 123;

Without the print, now press Add Before, area will be clean again ... BUT, write this:

print(i);

and press Run, you'll read 123 in the output panel.
This mean that precedent code is in ram, and is present on output but not in the area.
Of course, if you Add Before print(i); , this will be executed after var i:int = 123;

This is useful to add classes or other scripts, just tested.
Now, if you press Get Before, the entire content will be added to the area, after current one, if any.

Finally, with Clear Before, everything in the Ram will be cleaned.

Simple? Last thing: every time you press Run, code is compiled in a new enviroment.

That's it, and sorry for this horrible debugger ... but time is never enough :)

Sunday, February 24, 2008

How to inject protected methods in JavaScript

As you know, JavaScript requires different strategies to emulate private methods.
I personally wrote some weird experiment to automatically emulate private scope behaviour.

However, my experiment was RegExp based ... a really bad way to emulate private scope behaviour for a lot of reasons.

At the same time, you can implement private scope methods only inside the constructor and this means that you cannot base your code with both prototype and private scope.

// non sense example
function MyConstructor(value){

function privateMethod(){
return this.value;
}

this.get = function(){
return privateMethod.call(this);
}

this.value = value;
};

MyConstructor.prototype.getAgain = function(){
return privateMethod.call(this);
// error, privateMethod has a different scope
};


Basically, the reason that make prototype better than constructor with privileged methods, as get one is, is that core doesn't need to parse and/or create functions for each instance.
Another reason to prefer them is that you can add, remove, or change, a single function affecting every instance.
A good behaviour specially with a browser based language, as JavaScript is, that allow developers to write dedicated browser methods once, instead of check and change behaviour each time and for each instance.


The bridge strategy


One way to solve scope problems betwen external prototype based methods and private constructor functions, is to use a bridge.

// basic bridge example
function MyConstructor(value){

function privateMethod(){
return this.value;
};

this.callPrivateMethod = function(name, arguments){
return eval(name).apply(this, arguments);
};

this.value = value;
};

MyConstructor.prototype.get = function(){
return this.callPrivateMethod("privateMethod", arguments);
};

var demo = new MyConstructor("test");
alert(demo.get()); // test

Basically, the bridge method is a privileged wrapper, but it is inside the correct scope and that's why it can call function privateMethod without errors.
Seems cool? But it isn't so cool .. and that's why:

  • the bridge method is public, everyone could override them in every other place and for every instance

  • each instance creates every private function plus a bridge method, there's no prototype behaviour

  • last but not least, we are using eval ... and this means, for 99% of times, that we are using a bad code design



Public methods overload strategy


A different way to solve this problem is to inject your private methods inside the instance each time you call a public one.
You can do it once, and forget private scope methods for ever, using them in a natural way inside every other one.
To do it, you need to change at least one time each public method, overloading them during constructor assignment.
This is a final result example:

MyClass = Create(

// constructor
function(value){
this.value = value;
},{
// one or more prototypes
sum:function(num){
return this._checkNumAndSum(num);
}
},{
// one or more private methods
_checkNumAndSum:function(num){
alert(this.sum === MyClass.prototype.sum); // true
return typeof num === "number" && isFinite(num) ? this.value += num : undefined;
}
}
);

var demo = new MyClass(3);
alert(demo._checkNumAndSum); // undefined
alert(demo.sum(2)); // alert true and after them returned value is 5
alert(demo._checkNumAndSum); // undefined

This list rappresents Create function goals:

  • prototype based, it overloads directly the prototype object and it does not create protected functions each time

  • natural code, you do not need to change your code as is for bridge, during protected method execution


This one rappresents Create function limits:

  • you cannot share a prototype object, even if this phrase doesn't make sense for most of you

  • public methods execution time will be a bit slower, where that "bit" is not a real problem but for performances maniacs it will

  • injected methods are protected and not private, these are visible during method execution itself


To better understand last point, look at this example:

function visibleMethod(instance){
alert(instance._checkNumAndSum);
};

// ... same code of precedent example with this change

// one or more prototypes
sum:function(num){
visibleMethod(this);
return this._checkNumAndSum(num);
}


Since I guess that above situation is not so common, I think that's a good thing to let you know that protected methods are visible during each protected or public method execution.
Pure OOP has a different meaning for protected methods, it is based on possibility to use those methods from a subclass.
In my case, I choosed protected word because private one, usually not accessible from subclasses, is a word that loose its concept in the instant you can access that method outside the object.
I know probably my choice wasn't so serious, but for a prototype based inheritance I think it makes sense :)

Finally, what you really need to test my examples, is this function:

function Create(constructor, prototype, protected){
// (C) Andrea Giammarchi - Mit Style License
switch(typeof protected){
case "object":
var list = [],
i = 0,
key;
for(key in protected)
if(protected.hasOwnProperty(key))
list[i++] = {key:key, callback:protected[key]};
for(var key in prototype)
if(prototype.hasOwnProperty(key))
prototype[key] = (function(prototype){
return function(){
for(var i = 0, length = list.length; i < length; i++)
this[list[i].key] = list[i].callback;
result = prototype.apply(this, arguments);
while(i--)
delete this[list[i].key];
return result;
}
})(prototype[key]);
default:
constructor.prototype = prototype;
break;
}
return constructor;
};

Enjoy my code and have fun with JavaScript!

Wednesday, February 20, 2008

packed.it goes off line !

... or, to be honest, that's what it's gonna do in few days, but PHP version is out!

You can find every information about server side version of packed it directly in this page.

I am not joking when I said that packed.it is probably the fastest optimized client files server you can find over the net, even with an uncompiled program language like PHP.

The key is the JOT compiler, compile one time, serve all the time without paranoia, saving bandwidth for both server and client, avoiding the usage of gz handlers, avoiding runtime compression, avoiding whathever you want, and finally, having the possibility to serve js, css, or both with a single file.

Discover by yourself how long server need to serve, for example, jQuery ... less than one millisecond without louds of requests ... please look at X-Served-In header, if you do not trust me :P

What's new? You do not need to pass in packed.it site to compile your projects, you can just serve and compile them directly from your one.

To Do:
Python PSP and SWGI version, C# version and finally, Jaxter version for server side JavaScript auto compilation in itself language ... does it sound good?

Enjoy packed.it, and please do not ignore totally PayPal Donation :D

Cheers

Tuesday, February 19, 2008

[PHP] PartialFunction and PartialMethod

I found really interesting this John Resig post, about partial functions in JavaScript.

For a weird problem, I choosed to use the same behaviour, but with a different language: PHP

Sometime PHP is more flexible than we think (at least me), and this is the result of my little experiment:

class ReflectionPartialFunction extends ReflectionFunction {

protected $args;

public function __construct($name){
parent::__construct($name);
$this->args = func_get_args();
array_splice($this->args, 0, 1);
}

public function invoke($args){
$args = func_get_args();
return $this->invokeArgs($args);
}

public function invokeArgs(array $args){
return parent::invokeArgs(array_merge($args, $this->args));
}

public function rinvoke($args){
$args = func_get_args();
return $this->rinvokeArgs($args);
}

public function rinvokeArgs(array $args){
return parent::invokeArgs(array_merge($this->args, $args));
}
}

class ReflectionPartialMethod extends ReflectionMethod {

protected $args;

public function __construct($class, $name){
parent::__construct($class, $name);
$this->args = func_get_args();
array_splice($this->args, 0, 2);
}

public function invoke($object, $args){
$args = func_get_args();
return $this->invokeArgs(array_shift($args), $args);
}

public function invokeArgs($object, array $args){
return parent::invokeArgs($object, array_merge($args, $this->args));
}

public function rinvoke($object, $args){
$args = func_get_args();
return $this->rinvokeArgs(array_shift($args), $args);
}

public function rinvokeArgs($object, array $args){
return parent::invokeArgs($object, array_merge($this->args, $args));
}
}


While these are two simple tests:

function mul($num, $fixedParam = 0){
return $fixedParam * $num;
}

class Test{
protected $num;
public function __construct($num){
$this->num = $num;
}
public function me($num, $fixedParam = 1){
return $this->num * $fixedParam * $num;
}
}

$partial = new ReflectionPartialFunction('mul', 12);
echo $partial->invoke(2); // 24

$partial = new ReflectionPartialMethod('Test', 'me', 12);
echo $partial->invoke(new Test(2), 2); // 48


Now it's your round to find real applications ;)

update
Honestly, I need right arguments and my first implementation put partial arguments before the others and not at the end.

With this update you can use, by default, argments at the end of the function, but if you want to use them before, just call rinvoke or rinvokeArgs (r means put recieved arguments, during invoke or invokeArgs, on the right, at the end)

function mul($paramFixed, $num){
return $paramFixed / $num;
}
$ref = new ReflectionPartialFunction('mul', 4);
echo $ref->rinvoke(2); // will be 2, as 4 / 2

Wednesday, February 13, 2008

jQuery + jQuery UI + Full Flora Theme ... less than 32Kb

Don't You trust me? It's so diabolically simple with packed.it ... and more than a professional Web Developer complained about "why on heart noone talk about that service" :D

It's not packer, it's not YUICompressor, It's the only one that cache both CSS and JavaScript in a single file ... it's for PHP4, PHP5, Python wsgi, Python psp, C#.NET ... so, what are you waiting for?

Ok, I'll let you try this full package:
jQuery 1.2.3 and jQuery UI 1.5b with full Flora Theme included.

Enjoy ;)

P.S. jQueryUI.html example file calls jQueryUI.php, jut change estension in your server if you want python or .NET

Saturday, February 09, 2008

The fastest way to know if someone "did it" ...

I know I choosed a weird title, isn't it :?

Today I have two small and useful tips and tricks for JavaScript.

The first one, lets you know if someone extended the Object.prototype

if((function(k){for(k in {})return true;return false})()){
// do stuff that care about Object prototype
} else {
// do stuff that doesn't care about Object prototypes
}

Simple, quick, and dirty ;) and this is another example:

function didIt(k){for(k in {})return true;return false};

if(didIt()){
// stuff prototype
}

One thing to take care about is the usage of a function instead of a variable.
Since some script could run other scripts dinamically, you can't trust in a single time check.

The second trick is really useful for function that accept a switcher argument.
For switcher argument I mean methods or function that accept true or false as argument.
The simplest way to have a switcher is obviously sending the value, but in this case we can't have a default behaviour.

Simple is to choose a "false" behaviour as default one

function addOrRemoveStuff(dontDoIt){
if(dontDoIt){
// someone sent a true value
} else {
// default behaviour, dontDoIt is false or undefined
}
}


So what's new? Nothing, yet, but try to guess about a different default ... a true value as default ... think ... think ... think ... did you find them? :)

function addOrRemoveStuff(doIt){
doIt = !arguments.length || !!doIt;
if(doIt){
// default behaviour, doIt is true
} else {
// someone sent a false value
}
};

addOrRemoveStuff(); // true
addOrRemoveStuff(false); // false
addOrRemoveStuff(1); // true


This simple thing is present, for example, in jQuery.smile method.

$("div.post, p.comments").smile(); // add smiles
$("div.post, p.comments").smile(false); // remove smiles

Enjoy these tricks, and this week end as well :)

Thursday, February 07, 2008

JSmile for jQuery ;)

As I said one post ago, I've created a jQuery dedicated version of my simple JSmile project :geek:

Here you can find the demo page, qhle here the automatic generated source

What's new?
It's so simple

$(function(){
$(document.body).smile();
});


Use $("one or more smiles containers").smile(true or false) to add/remove smiles from your pages.

See you ;)

jQuery minor improvements

Update
This post has an "official" link, now, directly in devpro :)
--------------

These are just few fixes / improvements of some jQuery stuff.


(function(o){for(var k in o)jQuery[k] = o[k]})({

// IMPROVED: Evalulates a script in a global context using a specified JS version, if any
globalEval: function( data, version ) {
/** Examples
$.globalEval("let(a = 1)alert(a);"); // error
$.globalEval("let(a = 1)alert(a);", 1.7); // OK, alert 1

(function(){
var test = 1;
$.globalEval("test = 2");
alert(test); // 1
})();
alert(test); // 2
*/
data = jQuery.trim( data );
if ( data ) {
var script = document.createElement("script");
script.type = "text/javascript";
if ( version )
script.type += ";version=" + version;
if ( jQuery.browser.msie )
script.text = data;
else
script.appendChild( document.createTextNode( data ) );
with(document.getElementsByTagName("head")[0] || document.documentElement)
removeChild( appendChild( script ) );
}
},

// IMPROVED: optional strict comparation
inArray: function( elem, array, deep ) {
for ( var i = 0, length = array.length; i < length; i++ )
if ( (deep && array[ i ] === elem) || (!deep && array[ i ] == elem) )
return i;

return -1;
},

// FIXED: ( typeof array != "array" ) .... excuse me ???
makeArray: function( array ) {
if(array instanceof Array)
var ret = array.slice();
else
for(var ret = [], i = 0, length = array.length; i < length; i++)
ret[i] = array[i];
return ret;
}

});


Next post will be about my define function for jQuery, a typeOf suggestion, and finally JSmile integrated in jQuery ... so please, stay tuned :)

Monday, January 21, 2008

JSmile ? Even more simple with an AntiPixel ;)



I've created an antipixel gif to add JSmile easily in your site too.

What should you do to add JSmile?
Copy and past this code wherever you like in your website.

<img
src="http://packed.it/JSmile/JSmile.gif"
alt="JSmile - by Web Reflection"
title="JSmile - by Web Reflection"
onclick="if(window.JSmile){JSmile(document.body)}else{var i=setInterval(function(){if(window.JSmile){clearInterval(i);JSmile(document.body)}},20),s=document.createElement('script');s.src='http://packed.it/JSmile/?js';document.body.appendChild(s)}"
/>


Done? Perceft, now when you want, click in JSmile antipixel and your site will be more rich.

Too simple? :o

Sunday, January 20, 2008

JSmile - smiles everywhere in less than 1Kb!

Update !
Now you can see JSmile in action directly in this blog ;)
I added just this line:

// this element is smile free :)
// noone will be added in code or pre tags
JSmile(document.body);

and the magic happened :D

Come on guys, we have totally unobtrusive smiles for blogspot and every other blog site too 8-)

P.S. script, code, pre, and noscript tags are preserved. No changes will be done by JSmile. If you think about another element that shouldn't be parsed, please tell me :geek:
----------------------------------------------------




Do you want to add some graphic smile in your site?

Do you like GTalk and you think that inline smiles should be cool for your website too?

Are you worried about obtrusive smiles?

Are you worried about server side parsers?

Are you worried about other libraries and JavaScript events for each element?

... forget everything and use JSmile, a new library in less than 1Kb (gzipped) that uses DOM instead of innerHTML, could be compatible with every other kind of library and add smiles using a single site, avoiding cache or bandwidth problems!

Do you want to try an example?

Go to this page: http://ajaxian.com/archives/winter-holiday-christmas-lights

Look at the text, you could find some smile like ;) ... now, if you use firefox, try to cut and copy this piece of code in your ulr:

javascript:(function(){var script=document.createElement("script");script.src="http://packed.it/JSmile/?js";script.onload=function(){JSmile(document.body)};document.lastChild.appendChild(script)})();


Can you see the difference?

Text nodes are changed in a totally unobtrusive way.

No paranoia guys, a person without images will read alternative text, a person with image will read the title if they'll move mouse over the smile.

A person that use JS events can't be worried, events are for other kind of nodes, not for text nodes .... a person without JS enabled will see textual smile .... a person with JS enabled will see a smile using its cache, because of single url and unique smile identifier ... do you need more?

Ok, you should use this function wherever you want and choose wich part of your page should be parsed, sending simply dom node to JSmile function:

JSmile(document.getElementById("testMe"));


Seems interesting? This function could make your site cooler without any effort.
Include JSmile in your head tag and use JSmile function wherever you like.

Currently this function uses phpBB default postable smiles but in the future new smile themes will be available.

Enjoy JSmile and have fun with unobtrusive JavaScript!

Wednesday, January 02, 2008

PAMPA - On Line version 0.6

After few months without updates, I am proud to announce last version of my Portable AMP Application for Windows.

Changelog

  • New customizable tray icon, with different color for each status (active/unactive)

  • New version of PHP, 5.2.5, with some extra dll active by default (APC and rfc for upload progres)

  • New Apache 2.2.6 and MySQL 5.0.45 Comunity

  • New options on system tray icon using right mouse button

  • Removed TurbodbAdmin, added last version of phpMyAdmin by default some minor fixes or checks



You can find everything in the official PAMPA site.

Enjoy them :-)


P.S. I am sorry for possible server problems so please try later if You can't download or visit the official site.

Monday, December 31, 2007

[OT] Never forget old school!

Another year has gone, new technologies are coming but please never forget genuine old style. Happy new year to everyone from me and old "friend" :D

Saturday, December 29, 2007

Is JSON forgetting something?

I played many times with JSON serialized data, creating odd alternatives too like JSTONE or JSOMON.

Few years ago I created even a PHP compatible serializzation but nowadays, with PHP5, json_encode and json_decode are natively integrated in PHP language and, at the same time, even faster than old serialize and unserialize global functions.



The big difference between JSON and PHP serializzation


Both JSON and PHP Serialized data have the same goal: transport objects and data over http protocol or storage these informations inside a cookie, a database or why not, a file.
However, PHP serialize and unserialize functions do more things than JSON serializzation, adding charset/indexes informations transporting even private or protected parameters.

With JavaScript 3rd edition We have not latter kind of properties so we shouldn't care about this limit during serializzation.

This is probably the most important difference between these two different serializzation but there is another one that should be easily implemented in JavaScript too: magic __sleep and __wakeup methods.



What do we need


The most important information we need to make JSON more magic than ever should be the constructor name. Without this information every kind of instance will lose its special methods/properties reducing them as a common Object.
Usually, this is exactely what we would like to transport, keys and values or, in the case of Array, only its values.
I'm thinking about something like that:


function A(){};
function B(){};
B.prototype.__wakeup = function(){
this.d = String.fromCharCode(this.c + this.a.charCodeAt(0));
};

var a = new A;
a.a = "b";
a.c = "d";
a.e = new B;
a.e.a = "b";
a.e.c = 3;
alert(encode(a));

// $("A",{"a":"b","c":"d","e":$("B",{"a":"b","c":3})})

I think that original objects doesn't need their constructor name.
In this way the unique change is for different instances and JSON syntax is quite the same.

With a string like that we should use eval too in a simple way:

function decode(str){
function $(constructor, o){
var result = eval("new ".concat(constructor)), key;
for(key in o){
if(o.hasOwnProperty(key))
result[key] = o[key];
};
if(typeof result.__wakeup === "function")
result.__wakeup();
return result;
};
return eval(str);
};

function A(){};
function B(){};
B.prototype.__wakeup = function(){
this.d = String.fromCharCode(this.c + this.a.charCodeAt(0));
};

var o = decode('$("A",{"a":"b","c":"d","e":$("B",{"a":"b","c":3})})');

alert([o instanceof A, o.e instanceof B, o.e.d]);


The __wakeup magic method should be used to do something before the object will be assigned, extremely useful in a lot of common situations.



What about __sleep?


The magic __sleep method should be the same used with PHP.
A simple prototype that could do everything but that needs to return properties we want to serialize.

This should be a JSON parser problem that could check every instance and use, only if it's present, its __sleep method.



Improvements



  • constructor name for instances that are not just objects

  • better server side parsers to manage instances without loosing their constructor name

  • a global name for dollar function, if some library use them as constructor too to avoid problems during instance creation (or a simple global-scope evaluation for each new "constructor" assignment)




This is just a personal brainstorming/proposal and I would like to know what do you think about that.

P.S. marry Christmas and happy new year :-)

Friday, December 21, 2007

JavaScript Iterator for IE and other browsers

This is just my proposal to add Iterator in Internet Explorer and other browsers too.

(function(){

function Iterator(obj, name){
// Iterator(obj) and new Iterator(obj) behaviour
if(this instanceof Iterator){
var i = 0,
result = [],
skip = false,
key;
for(key in obj){
result[i++] = name ? key : [key, obj[key]];
this[key] = undefined;
if(!skip && (key == "constructor" || key == "toString" || key == "valueOf"))
skip = true;
};

// solve IE problems
for(var l = 0, arr = ["constructor", "toString", "valueOf"]; !skip && obj.hasOwnProperty && l < arr.length; l++){
if(obj.hasOwnProperty(arr[l])){
result[i++] = name ? arr[l] : [arr[l], obj[arr[l]]];
this[arr[l]] = undefined;
};
};

// add next method if any next in object
this.next = function(){
if(i === result.length)
throw new StopIteration;
else
return result[i++];
};

// reset result "pointer"
i = 0;
}
else
return new Iterator(obj, !!name);
};

function StopIteration(message, fileName, lineNumber){
this.message = message;
this.fileName = fileName;
this.lineNumber = lineNumber;
};
StopIteration.prototype = new Error;

// global scope check
if(!this.Iterator)
this.Iterator = Iterator;
if(!this.StopIteration)
this.StopIteration = StopIteration;
})();


// test it!
var iter = Iterator({a:"b", next:"c", toString:"hello"}),
output = [];
try{
while(true)
output.push(iter.next());
}
catch(err){
if(err instanceof StopIteration)
output.push("End of record");
else
output.push("Unknown error: " + err.description);
};
alert(output.join("\n"));


The best way to use them is with iter.next() method but you could use a for in loop too.
However, in latter case if the object has a next property, it will be overwrote by dynamic method but this problem apart, enjoy iterators :-)

Thursday, December 20, 2007

packed.it ... again online

I am sorry for last days while packed.it wasn't working as expected because of new server.
It seems to be faster than precedent one so thank you again Daniele , I'll write your link as soon as I can :-)

Enjoy both JavaScript and CSS compressed files in a single one, enjoy packed.it!

Monday, December 10, 2007

FireFox, Safari, and Opera ... JavaScript Conditional Comment

I've still written a comment in John Resig blog about Re-Securing JSON and FireFox or Safari 3 const behaviour to create an immutable function, called Native, and to retrieve original Array, Object, String or other constructors.

This is the function:

const Native = (function(){
const NArray = Array,
NBoolean = Boolean,
NDate = Date,
NError = Error,
NMath = Math,
NNumber = Number,
NObject = Object,
NRegExp = RegExp,
NString = String;
return function(Native){
switch(Native){
case Array:return NArray;
case Boolean:return NBoolean;
case Date:return NDate;
case Error:return NError;
case Math:return NMath;
case Number:return NNumber;
case Object:return NObject;
case RegExp:return NRegExp;
case String:return NString;
};
};
})();

// Example
Array = Native(Array);
eval("[1,2,3]");


At the same time I've talked about IE behaviour and its missed support for const.

While I was thinking about that I imagined a way to use a piece of code, in this case the keyword const, compatible with every browser.

It should sounds simple, just use the well know trick IE=/*@cc_on ! @*/false; followed by if(IE) ... but ... hey, I need everytime to create a double version of the "same script" ... is it good?

Try to imagine a variable that should be a constant for every compatible browser but at the same time should be declared just one time ...

const MyConstant = 1;


With every day practices we should use a try catch or some strange trick to evaluate a const declaration ... don't we?

But we have a particular behaviour of the conditional comment ... it should contains a comment itself too, sounds cool?

/*@cc_on // @*/ const
Native = function(){
// whatever You need
};


Can anyone trigger an error with above piece of code? :-)

In this way FireFox 2+, Safari 3+ (I don't know about 2), and Opera 9+ could work without problems disabling Native variable re-declaration while every IE browser will ignore the const keyword.

I suppose this trick is not so new but never as this time it should be useful to make code more slim and efficient.

Instant Update
The usage of const inside the private scope of Native function declaration is not so useful (just a little bit of paranoia :D) but in these cases we could use a better trick to create local variables with internet explorer too.

This is an example:

Native = (function(){
/*@cc_on var // @*/ const
NArray = Array,
NBoolean = Boolean;
return function(Native){
return Native === Array ? Narray : NBoolean;
};
})();

Above example shows how should be possible to initializzate multiple variables using a comma and respecting the private scope.
Internet Explorer will use var while every other browser will try to use const if it's compatible.

Sounds even better? I hope so :-)

P.S. Native function is quite interesting, imho, that's why I choosed to add them in devpro.it

Wednesday, December 05, 2007

Looking for a job in London ... or not?

It's about 2 weeks that I'm studying in London to improve my English knowledge, specially my spoken one (I know, written is not so perfect too).

I put my cv on line in a famous recluting search engine but it seems that most interested people are Agency's employees that usually look for generic IT - Web masters.

I would like to explain my "strange situation": I am not absolutely a web designer, I do know quite nothing about graphic, I could just know how to start Gimp!!! :D

It seems that if You know quite perfectly ActionScript 1.0/2.0, that's basically ECMAScript 3rd edition or, in case of 2.0, 4th one closed, you can be only a Web Designer and not a programmer, even if You know Flash Player bugs and you're able to find out workarounds.

It seems that if You know deeply JavaScript (best practices, OOP, Ajax, cross-browser/platform development, bugs, common libraries suggestions) it's not important ... just a preferred plus ... but at the same time everybody is looking for Ajax and Web 2.0 skilled developers, a role that absolutely requires a good programming background (not just a bit of DreamWeaver).

It seems that if you know different languages or technologies ... there's always a missed one.
How can a person to be "senior in every program language"?
I can't call their "expert or senior everything developers", a part for someone who has at least 20 years or more experience.

However, excellent OO PHP 4/5,JavaScript,ActionScript,(x)HTML,CSS,XML skills aren't enough while a good knowledge of C# for ASP.NET or MONO, and Python is not enough as a technical plus.

Maybe someone should be interested in my good database skills, starting from SQLite 2/3 to MySQL 3/4/5, passing inside PostgresSQL ... but it's not enough.

What about security practices and code optimization skills? Who cares about that!

As sum, and as someone said before me: please hire me !!! :-)

Best regards,
Andrea Giammarchi

Thursday, November 01, 2007

A quite totally standard enviroment before ECMAScript 4th Edition in less than 3Kb - JSL 1.8+

JavaScript Standard Library Revision


After the success of my old JSL project I learned more about JavaScript and I found some trick to solve different problems such setInterval and extra arguments for Internt Explorer, a function to evaluate code in a global scope with every browser as Internet Explorer does with its proprietary execScript.

Since these days We're waiting for ECMAScript 4th Edition, aka JavaScript 2 but since We always don't know when it should be really usable within productions, I choosed to create a revisited version of JavaScript Standard Library.

I removed Internet Explorer 4 support but I modified a lot of common prototyes to make them faster, more standard and more scalable than ever.
You can use, for example, every JS 1.6+ Array.prototype with HTMLCollections too as it's possible from many Years with FireFox or Safari:

Array.prototype.forEach.call(document.getElementsByTagName("div"), function(node){
alert(node.innerHTML);
});


I fixed different standard behaviours and I implemented setTimeout and setInterval.
I add execScript, not standard, but really useful when You need to evaluate JavaScript in a global scope with FireFox, Safari, Opera and every other as Internet Explorer does from many years with its own execScript global function.


JSL creates a quite totally standard JavaScript 1.6+ enviroment adding prototypes only to browsers that don't support them or that have different behaviours and everything in a hilarious size of 2.53 ... 2.86 Kbytes (gzipped) - new size is caused by an instant update, an XMLHttpRequest constructor (a wrapper) to allow every IE 5 to 7 browser to define XMLHttpRequest prototypes too.

With JSL You can forget your own not always standard prototypes implementations so every library size could decrease its code quickly, basing them on standard JavaScript 1.6+ enviroment and increasing performances for every standard browser like FireFox or Safari (about 40% of users ... growing up every day!).

This is the last chance to have a more standard Internet Explorer implementation because if We need to wait their fixes We should go better to sleep.

Have fun with JSL Revision and a quite real ECMAScript 3rd Edition enviroment.

Monday, October 29, 2007

[COW] JavaScript define PHP like function

This time my personal COW is a quite totally cross browser function to define a JavaScript constant.

With FireFox or Safari a const variable should be nested or global but the most important thing, it cannot be assigned two times

const scriptCantChangeMe = "some text";
scriptCantChangeMe = "something else";
alert(scriptCantChangeMe); // some text


A constant should be every kind of JavaScript variable and if this feature will be available on future versions of Internet Explorer and Opera, a lot of security problems should be solved (think for example about JSON, Array, Object and every other constructor, method or callback).

Unlikely We can't use this feature with Opera browser and, quite more important, Internet Explorer doesn't support JavaScript constants.

The only way to create a global scope constant variable with Internet Explorer is using another language: VBScript

This IE dedicated language supports PHP like defined constants: scalar values like integer, float, string or boolean.


JavaScript define function


This function works like PHP define one, except for last argument, case-sensitive, and it is compatible with Internet Explorer (maybe every version), FireFox 2 or greater, Safari 2 or greater and finally Opera 9 o greater too.

define("MY_NOT_MUTABLE_VALUE", 123);
alert(MY_NOT_MUTABLE_VALUE); // 123
MY_NOT_MUTABLE_VALUE = 456; // error with Internet Explorer
alert(MY_NOT_MUTABLE_VALUE); // 123 with both FireFox and Safari


The most important thing is that You can't change arbitrary a defined constant and it should be useful in many different cases.

Only Opera 9 has a wrong const implementation because it's just a var alias and not a real constant creation.

Since Opera hasn't a watch Object prototype and since a prototype should be always defined everywhere, this last browser is compatible but it allows value mutation so please remember this when (and if) You choose to use my define proposal.

Finally, please remembre that a constant should respect some rules:

  • its name must be UPPERCASE (MY_CONST instead of MyConst or my_const)

  • its name should have a dedicated prefix/suffix to don't be intrusive (MY_LIB_NAME_INITVALUE instead of INITVALUE)



Remark: to ensure cross browser compatibility every value is parsed by function, checking for its toString native or assigned returned value.
This means that define("MY_BOOL", "true") creates a constant called MY_BOOL that will be exactly a boolean true value and the same thing happens if You use "false" that will create a boolean false constant.
This is true for numbers too:

define("MY_STRING", "123") === define("MY_NUMBER", 123); // true
define("MY_STRING", "true") === define("MY_BOOLEAN", true); // true
define("MY_STRING", "-123.456") === define("MY_NUMBER", -123.456); // true


That's all :-)

Thursday, October 25, 2007

adsense destructive function!

Google AdSense is a free and cool service and is widely used inside many sites.

It allows site managers to get paid while they show their content ... it's great and thank You Google for this service.

However adsense uses a function that's probably the most obtrusive one You can use or find while You write JavaScript.
This function is exactely this one:

function $(b){
for(var a in K){
b[a]=null
}
}

Using them with own objects is absolutely not a problem but what kind of object do You think that b is? The Window one!

It's absolutely a non-sense for a service that uses JavaScript inside a closure to respect other libraries and to be free to use every name it needs to be executed!


Why this function is an obtrusive monster?


We always use third party libraries or We write JavaScript directly but in both cases We (others) should implement a generic Object.prototype inside our code ... just think, for example, to toJSONString prototype, OK ?

Now suppose that You write your own function, called toJSONString to manage everything else, objects too.

function toJSONString(){
// doStuff
};


Just add adsense in Your page and everything will not work ... seems interesting?

The right thing is that Object.prototype is always a problem if You don't use method hasOwnProperty inside a generic for(var key in obj) loop.
If You forgot them You should parse, manage, modify, properties that aren't part of your code (however these shoulkd be a part of your code too) and that's exactely what adsense does at the end of its execution.

The reason seems to be simple, adsense script would remove every global variables You write everytime You need them to allow a single page to contain different versions of adsense without any sort of problem with precedent settings.

At the same time every method or parameter assigned to Object.prototype will be "globally deleted" (becoming a null value) so if DjProto called one prototype, for example, escape You'll never be able to use escape as a native function.
At the same time google adsense code itself should fail too because if I write 2 prototypes like these:

Object.prototype.escape = Object.prototype.encodeURIComponent = function(){
return escape(this.toString());
};

and I add one adsense in my page, next one will not be able to encode any kind of string that should be sent to Google service.

Cool?


A really simple and crossbrowser solution


Since Object.prototype.hasOwnProperty is available only in IE6 or greater (I can't remembre if IE 5.5 has it) Google shouldn't implement this check but it should implement another one even more simple but efficient for this purpose.

function $(b){
for(var a in K){
if(Object.prototype[a]!=K[a])
b[a]=null
}
}

In this way every JavaScript compatible browser will remove or will assign to null Google adsense global scoped K object properties only (that are, again, objects of this type google_rl_mode:{url_param:"rl_mode",gfp:0}) without enviroment destruction possibility :-)

Another trick should be this one:

function $(b){
for(var a in K){
if(/^google/i.test(a))
b[a]=null
}
}



Finally, this post should be helpful to understand better for in loops and problems adding Object.prototype parameters or methods ... and at the same time is another reason to pray that ES4 will be available as soon as Mozilla developers can - it simply let You define which property should be enumerable and which not!

Upload progress bar with PHP5, APC and jQuery

Yesterday I wrote a little tutorial (Italian language, sorry) that explain how to create an info panel while a file is uploaded.

Here You can view final result:


While this is the entire archive with everything You need to test by Yourself my code:
APCQuery

To test them You need PHP 5.2 or greater and APC enabled.
Please verify that rfc is enabled too:
extension=php_apc.dll
apc.rfc1867 = On


If You test them locally please remember to try form using big files (from 40Mb to 200M for fast PCs) changing php.ini upload_max_filesize and post_max_size directives (I suppose 200M is enough).

If someone is interested about an English version of tutorial I'll try to find time to translate them.

Tuesday, October 23, 2007

[ES4] ... good by my darlin' toy ...

... and

Welcome Control Over Performances !!!


I can't wait one more minute ... Go ES4 implementations, GO!

Saturday, October 20, 2007

[COW] locAction - hash JavaScript location wrapper

One of the problems using JavaScript and Ajax is history managment and location behaviour.
A good solution was found by backbase many months ago, using reserved hash location property to manage correctly interactions and history itself.
This COW should be used to manage hash property as a full compilant location, allowing developers to know pathname, search (query string) and in some cases (JavaScript and Opera) hash itself too.

You can view a demo in this page comparing native location and wrapped one using locAction callback.

Please note that backbase too removed this practice from its site (which problems?) but my locAction proposal is compatible with every kind of JavaScript compatible browser (of course, IE4 and NN4 too).

These are few examples:

// basic example - standard location

href: http://localhost:80/?key=value&other
protocol: http
hostname: localhost
port: 80
pathname: /
search: ?key=value&other
hash:




// basic example - locAction(location)
// using http://localhost:80/?key=value&other#hash

href: http://localhost:80/hash
protocol: http
hostname: localhost
port: 80
pathname: /hash
search:
hash:



// full example - standard location
href: http://localhost:80/mypage.html?key=value&other#ajax/page.html?other=key&value
protocol: http
hostname: localhost
port: 80
pathname: /mypage.html
search: ?key=value&other
hash: #ajax/page.html?other=key&value




// full example - locAction(location)
// using http://localhost:80/mypage.html?key=value&other#ajax/page.html?other=key&value

href: http://localhost:80/ajax/page.html?other=key&value
protocol: http
hostname: localhost
port: 80
pathname: /ajax/page.html
search: ?other=key&value
hash:

As You can see with location You can manage directly a parallel/alternative JavaScript/Ajax dedicated url, accepting GET variables as different paths.
In few words You'll have two different address, one for JavaScript disabled browsers and one for JavaScript enabled browsers.

Both locations, original one and generated using locAction, will have same methods too: replace, assign and reload but locAction() object should be always use these methods (direct assignment is not allowed, however native location direct assignment uses transparently assign method so it's quite tha same).

What else? locAction generated object shoud accept hash string but not with Internet Explorer or Safari (at least 3).

Saturday, October 13, 2007

[COW] Web RAM - a JavaScript function to share safely strings

This time my COW is really strange as Web concept ... a total size of 256 bytes (seems hilarius?) to share strings inside each browser window.

This idea is not so new, I wrote JSTONE few months ago to do something similar, however it seems that JSTONE requires dedicated JSON implementation or something similar to work correctly.

Now, let me explain why I wrote this tiny function and for what it should be used for.


Random Access Memory


window.name is a string always present every time We open a window.
The cool, but not so secure, behaviour of this property is that this persists even if We change site or domain or We refresh page using F5.
While We use the same window, window name will be available, seems cool?
RAM function is capable to save a lot of informations using a Random Access strategy, where the "memory address" is created by yourself, using your personal keyword.
Both keywords and saved data can contain every kind of char excepted for \x00 one (End Of String or null char).

It's based on a sort of automatic namespace management but your keyword is not really your one but as is for libraries, everyone should use a dedicated namespace without conflicts, don't You agree?
Finally, window.name can save strings of hundred of thousand chars, I didn't find a limit for saved informations but as is for real RAM, if You turn off your PC (in this case browser window) it will be automatically resetted.


Why RAM function ?


These days I'm testing my last creation, packed.it, to find problems or to test decompression speed with big data size.
One thing I tough is that with packed code (using packed.it, packer or similar compressors), size is not the real problem as decompression CPU overload is.
I was try to find a way to cache or speed up unpack operation but every test I did failed (bad results).
That's why I created this simple function, to test clear code evaluation performances instead of runtime decompression, allowing users to unpack every kind of code 1 time each window instead of every time.
This means that during navigation in the same window, a new user will unpack code only first time but after first clear code creation procedure, You sohuld save them inside window.name and evaluate them in every other page viewed inside same browser window.
At the same time, if user will leave your page and then come back using back button it will have again code stored if external site didn't modify window.name or modify them without RAM function.
Finally, I could save an address, called for example jQuery :-) ... saving clear source and check them every time one page that use them is called:

eval(RAM("jQuery") || RAM("jQuery", function(p,a,c,k,e,d){/* ... */}));

Every link in the same window and every site viewed after this one should use same strategy to perform packed sources evaluations faster than ever because decompression will be performed only first time ... not a real solution but at least a simple way to optmize, a bit, navigation and decompression speed?

So, RAM function should be used to ... ?



  • save each kind of informations rappresented as a string (JSON as every other kind of string)

  • share common libraries between different pages / sites

  • evaluate big strings if compressor believes in RAM function



I'll try to do some test with packed.it, probably as option.
The battle is between a little overload of 256 bytes against 1 to 5 seconds for really big packed sources ... uhm ... what do You think is better?

Do I forget something? Uhm, both keywords and sources could use SOH char too (\x01) without problems but each SOH will be duplicated inside window.name and replaced before You'll read them again to preserve string as is when You get them using RAM.


<script type="text/javascript" src="RAM.js"><!--// Function RAM //--></script>
<script type="text/javascript"><!--//
eval(
/* from second time You visit this page */
RAM("my personal key") ||

/* only first time You visit this page */
RAM("my personal key", "alert('Hello World')")
);
//--></script>




Update 2007/10/15
DarkCraft sayd that NoScript doesn't allow many chars inside window.name when You change domain, reload the page or do something similar.

I wonder why NoScript guys allows few chars in window.name (someone shoud use them to save user and passwords, for example) instead of clear one ... however, RAM should work without problems with NoScript enabled browsers too, just using a try catch statement.

// RAM example for NoScript browsers
try{
eval(RAM("my lib")||"this=0")
}catch(e){
eval(RAM("my lib", (function(p,a,c,k,e,d){return 'alert("hello my lib")'})()))
};

If You use this piece of code NoScript enabled browsers will just "decompile" each time saved informations, if these contains special chars too.
Please remember that RAM goal is to believe in itself, it's quite obvious that if some malicius site/page/code replace informations or uses malicius version of common libraries RAM function should become totally insecure.

The best practice I could suggest is to use a "private mutable key":

try{
eval(RAM("jQuery-1.2.1-" + location.hostname)||"this=0")
}catch(e){
eval(RAM("jQuery-1.2.1-" + location.hostname, (function(p,a,c,k,e,d){return 'alert("hello my lib")'})()))
};

That in a session based enviroment should be something like this code:

try{
eval(RAM("jQuery-1.2.1-<?php echo session_id();?>")||"this=0")
}catch(e){
eval(RAM("jQuery-1.2.1-<?php echo session_id();?>", (function(p,a,c,k,e,d){return 'alert("hello my lib")'})()))
};

To be sure library is shared only during a valid session.
A random cookie should be good enough too but paranoia is always with us :D

Finally, in packed.it I'll add a RAM option based on project name, different each time.
These practices disable cross site library sharing but I hope one day malicious site, developers, will be banned from the Web (just a "little utopia")

Worry about gzip ? No problem, packed.it preferes DEFLATE

I didn't test so much DEFLATE version of packed.it service and it seems that this one didn't work correctly with some browser ( ... ehr ... sorry guys ).

So I've just fixed deflate version and in my tests it works perfectly ... so perfectly that I choosed to use DEFLATE as first generator option, instead of gzip.

It seems that gzip causes too many problems with some version of Internet Explorer while I have not just read anything something about DEFLATE problems too.

gzip VS DEFLATE ?


Well, it seems that DEFLATE performs a compression quite faster than gzip but packed.it goal is to forget runtime compression ... so this point doesn't matter while decompression speed should be a better plus, again, for DEFLATE.

At the same time DEFLATE seems free of has some problems with every compatible browsers ... and as You know, Internet Explorer is compatible with this compression too :-)

The result code should be more slim using gzip but We are talking about 2%, max 3%, that's not a problem with both big and medium / regular compressed sources.


So what's new ?


The news is that now packed.it generators (PHP 4 or 5, C# Mono or .NET, Python PSP or WSGI) works correctly with deflate version (now compressed respecting RFC 1951) and choose them as first option.
You can obviously change priority by yourself, if You think gzip is better, however I'll mantain this choice if anyone will tell me that DEFLATE has same or more problems that gzip.

"gzip" is the gzip format, and "deflate" is the zlib format. They should probably have called the second one "zlib" instead to avoid confusion with the raw deflate compressed data format. While the HTTP 1.1 RFC 2616 correctly points to the zlib specification in RFC 1950 for the "deflate" transfer encoding, there have been reports of servers and browsers that incorrectly produce or expect raw deflate data per the deflate specficiation in RFC 1951, most notably Microsoft. So even though the "deflate" transfer encoding using the zlib format would be the more efficient approach (and in fact exactly what the zlib format was designed for), using the "gzip" transfer encoding is probably more reliable due to an unfortunate choice of name on the part of the HTTP 1.1 authors.


Have a nice optimization with packed.it ! (and please let me know if deflate will cause problems that gzip didn't cause)

Monday, October 08, 2007

packed.it screencast ... (maybe) Yesss!!!

I didn't find a way to create a clean video, probably 450 pixels are not enought to show how does packed.it work?

However, I'll try to explain these two screencast.

First one - Ext JS Home Page - from 223Kb to 52Kb


This video shows a saved version of Ext JS Home Page.
This site uses a lot of external CSS, one imported and one in page but not every one is used by JavaScript disabled browsers.
Total CSS size is about 93,2Kb while 4 used JavaScript files size is about 130Kb.

With packed.it You can create a project using both CSS and JavaScript and the result will be a single file with total size of 52Kb, including both CSS and JavaScript.

I didn't add to project Google Analytics unrich.js file but this should be included without problems too saving other 15Kb.

As You can see (I hope), the result is even smaller on page, just three tags, using IE5 compatibility one, instead of 8 inside page ... these are few bytes less than original and layout is even more clean than ever.

CSS file dedicated only for JavaScript incompatible or disabled browsers is just 36Kb instead of 93 without optimization but as You know You could use packed.it to serve an optimized version of this file too (just change packed.it folder name to packed.css, for example, and change prefix inside automatic generator).




Prototype and Scriptaculous in less than a minute, from 230Kb to 38Kb



This second example just shows a JavaScript only project, Scriptaculous 1.7.1 beta 3 using prototype version 1.5.1
You just need to upload these sources and with a click You'll download full Scriptaculous enviroment, reducing size from 230Kb to 38Kb.

Using client compression too, every gzip or deflate incompatible browser will download about 90Kb instead of 230Kb, reducing bandwidth about 38% of original.

Sorry for missed audio and bad video quality, I'll try to do something better next time, ok? :-)

Saturday, October 06, 2007

new packed.it automatic content generator

packed.it service now creates archives with 3 types of automatic content generator: ASP.NET (C#), PHP (4 or 5) and Python (mod_python and psp or WSGI version).

These generators complete packed.it service and are usable with MyMin produced code too if You choose to manage your own projects by yourself.

Probably there will be future implementations (Java, Perl, Ruby), however today You can use packed.it to create optimized CSS and JavaScript for more than 80% of hosting solutions.

A special thanks to Cristian Carlesso for C# porting, He doesn't like my revision style so much ... but it works perfectly and it's more simple to mantain too (at least for me :D)

Have fun with packed.it :-)

Friday, October 05, 2007

MyMin project 1.0.1 available

I've just uploaded last version of MyMin project fixing only JSmin problems with regular expressions when it's not inside a closure, not after '{' or ';' allowing them to parse entire jQuery UI, for example, without problems.

This fix has been successfully tested on Python 2.5, PHP 5.2, C# 2 and JavaScript 1.3

You can find MyMin project description in this page while You can optimize CSS and JavaScript in a single file simply using my on-line packed.it service.

Have fun with optimizations and please feel free to post a comment if You find some bug using MyMin project, Thank You!

Thursday, October 04, 2007

A "little bastard" BUG using JSmin parsers

Update
It seems I found a valid fix for "strange" regular expressions. I suppose MyMin will be available tomorrow while packed.it has been just updated with last client version.

Have fun with packed.it and please tell me if some source cannot be parsed.





--------------------------------------
While I was testing every kind of source and CSS with my last creation, packed.it, I found a bug on JSmin logic, partially recoded inside MyMin project as JavaScript minifier (MyMinCSS and MyMinCompressor seem to work perfectly).

This bug seems to be present on every version linked in JSmin page.

I found this bug parsing jQuery UI + every CSS with my new service but one JavaScript file has one single, simple problem:

function(){return /reg exp with this ' char/;}


Bye bye JSmin, regexp will be parsed as string and an error will be raised.

The problem is reproducible just with a string that contains only this (so a source that begins and end with these 3 chars):

/'/

that's a normal regexp ... at this point I can be happy to found first packed.it and MyMin project bug and the coolest thing is that is inside a part of project that's not really mine :D

To solve this problem, just use
return new RegExp
or just asign reg to a var before return them ... it seems to be the only one bug I found parsing every kind of source. Did anyone solve them?

I know it's not so simple, just because a char by char parser cannot simply know if slash is for a division, a comment or a regexp.

Do You have any sugest to solve this problem? It will be really appreciated! :-)

Wednesday, October 03, 2007

Are You Ready To Pack ?

I'm pleased to announce my last revolutionary project called packed.it !

Just another minifier packer alternative ???


No guys! packed.it goals is to reduce using best practices both CSS and JavaScript sources in a single file.
You can write directly on JS area or in CSS one or upload one or more file, choosing which one should be executed before others.
Based on MyMin project, a personal revisit of JSmin plus a dedicated compressor and a CSS minifier for C#, JavaScript, PHP or Python languages, packed.it creates a project archive, in zip format, that will contain everything You need to server your files gzipped, deflated or clear for browsers or robots that does not support gz pages.


Not only JavaScript !


The innovative packed.it idea is to process both JavaScript and CSS to create a single project file just compiled to be served using gzip, deflate or clear text.
In this case your server will not need to do anything, just serve correct file verifying its sha1 summary to choose it browser need to download them or use them from its cache.
Any other JavaScript compressor system includes possibility to pack CSS too and the reason is really simple.

How many times You write CSS dedicated only for your client library?
How many times You use words such div, body, li, #some-id, float, width inside CSS using same words inside JavaScript too?
Think about document.body, var li, getElementsByTagName("div"), getElementById("some-id"), setStyle("width") and so on.

My personal compressor, inspired by fantastic Dean Edwards packer idea, creates a single list of keywords used inside both CSS and JavScript sources.

Its simple but efficient algorithm counts how many times one word is present inside merged sources, CSS + JavaScript, and orders them to put most common words at the begin of keywords list, moving before words with length bigger than others.

In few words, every word will be replaced inside source reducing its size from 30% to 60% and if browser is compatible with gzip or deflate, final size should be even less than 20% of original one.


Do You want to know more about MyMin ?


MyMin is originally based on JSmin C implementation but it was partially rewrote to be compatible with JavaScript conditional comments too (for example: /*@cc_on @*/ and //@cc_on) while MyMinCSS is a simply but powerful minifier dedicated only for CSS and totally wrote by myself.


Do You want to know more about MyMin Compressor ?


MyMin Compressor works with every kind of source. This mean that You don't need to respect any rule when You write your JS or CSS code just because it doesn't modify original output and result will be exactly the same.
Its also based on fastest decompression algorithm I could thought and sources parsed with this Compressor will be available quickly even using old computers.

Its decompression procedure is compatible with every recent browser (IE 5.5 or greater, FireFox 1 or greater, Safari 2 or greater, KDE 3 or greater, Opera 7 or greater, NetScape 6 or greater, others too!) and should be compatible with old browsers too just adding a little function like this one before decompression (required only with IE5 or lower).


Do You need something else to choose packed.it ?


I hope there's no reason to don't use packed.it service:

  • it's innovative

  • it's free

  • it's compatible with W3 validator and WatchFire too (WAI-AAA friendly)


Ok, I know, It's beta ... but it's just working so please tell me some question to create a useful F.A.Q. site section or tell me if something doesn't work as expected.

Regards, and have fun with Web 2.0 technologies !

P.S. I'm working to include a C# and Python variant to packed.it.php file (gzipped and deflated files just works with every language).
If You want to do it for me before I'll do that, please tell me and I'll put your credits in dedicated page, thank You :-)



Example using Ext (all both for JS and CSS)
ext-all.js + ex-all.css ... original size: 559.90 Kb
after packed.it conversion: one file, total size: 129.81 Kb :-)

Example using jQuery + jQuery UI + every CSS theme
From 260 Kb to 40Kb , about 15% :-)

Example using bytefx
From 18 Kb to 1.5 Kb , about 8% and Yessss, less than 2kb! :-)


Update
Please note that packed.it is beta and not totally debugged with different browsers.
However to be sure your JavaScript enabled browser is compatible with packed.it result projects just visit this page.

If You can read a text over a background #DDD body, Your browser is compatible with packed.it produced code.

Tuesday, October 02, 2007

Extended parseInt and toString with radix

With JavaScript You can parse a Number using its toString native function.
This one supports a radix argument, an integer between 1 and 37.


alert(
(10).toString(16) // a
);

alert(
(35).toString(36) // z
);


This method should be really useful but should be used to reduce integer size too.
The limit of this function is its max usable radix, 36, but is possible to extend this one? Of course :-)

alert([
(35).toString(63), // z
(61).toString(63), // Z
(62).toString(63) // _
]);

My Base63 implementation allows both toString(radix) and parseInt functions to be compatible with maximum possible radix.

For possible I mean only these chars: [0-9] [a-z] [A-Z] plus last special char _

These chars are compatible with \w RegExp syntax and this means that You can use less than 60% of chars to rappresent an integer value.

var myInt = 123456789012345,
myTinyInt = myInt.toString(63);

alert([
String(myInt).length, // 15
myTinyInt.length, // 8
myInt, // 123456789012345
myTinyInt // vlzFV_Fx
]);


At this point, with a small code overload, You could quickly trasform every \w match into original integer value.


alert(
"vlzFV_Fx.Az49_7".replace(
/\w+/g,
function(s){var b="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_",l=s.length,p=0,r=0;while(l--)r+=Math.pow(63,l)*b.indexOf(s.charAt(p++));return r}
)
); // 123456789012345.36280109005


Interesting? Just think, for example, about an array of integers and a JSON like client/server interaction.

I hope this will be useful, regards.