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

Thursday, July 26, 2007

Quick Fix - Internet Explorer and toString problems

As You can read on precedent post I'm testing common libraries extend behaviour, both for objects or constructors.

One feature that many developers seems to ignore is IE behaviour when an object contains an explicit toString method.

Look at this simple example:

for(var key in {toString:function(){return "bye bye IE"}})
alert(key);

now test them with IE 5, 5.5, 6 or last 7 version.

What's up? ... absolutely nothing ... so what the hell?

IE doesn't recognize that toString method as explicit one but it "thinks" that's a native one.

This means that a lot of extend functions doesn't assign correctly this method if client broser is IE so every extended object will simply have native or prototyped toString method and not new explicit one.

How to fix this IE behaviour ?

// generic object/instance
var o = {
a:"a",
b:"b",
toString:function(){
return "hello IE too"
}
};

for(var key in o){
// doSttuff ... for example
alert(key);
};
/*@cc_on if(o.toString!=={}.toString){
// doStuff ... for example
alert(o.toString);
}@*/

Since only IE has this problem a conditional comment should be a good solution but this is not required, every other browser will simply check/assign one more time toString method if present.

You can use Object.prototype.toString instead of {}.toString but I think performances are not a problem in both cases.

What are libraries that don't care about this IE problem?

It seems that jQuery, MooTools and probably other libraries don't care about this IE problem while dojo, for example, does more than one check:

if(dojo.isIE &&
(typeof(props["toString"]) == "function") &&
(props["toString"] != obj["toString"]) &&
(props["toString"] != tobj["toString"])
)
obj.toString = props.toString;


Dean Edwards checked valueOf prototype too, so the complete fix should be this one:

/*@cc_on
if(o.toString!==Object.prototype.toString){
// doStuff
}
if(o.valueOf!==Object.prototype.valueOf){
// doStuff
}
@*/

Wednesday, July 25, 2007

JavaScript prototypal inheritance using known libraries

JavaScript is a "quite old" scripting language but every day there's some news about its normal behaviour or some common code ... well, today is my round :-)

There are a lot of frameworks or libraries We use every day but I think every JS developer should know atleast basic JavaScript prototypal inheritance.
It seems to be the ABC of this wonderful scripting language but if You'll read this post I suppose You'll be surprised!

Let me start with a simple example about JavaScript inheritance, a constructor A with just one prototyped method and a sort of subclass B that would be extend A one.
So, this is the A constructor:

function A(){};
A.prototype.constructorIs = function(F){return this.constructor === F};

// alert((new A).constructorIs(A)); // true

This is a basic constructor example and every instance will inherit constructorIs method.
This one will return instance.constructor and compare them with a generic constructor Function.
Well, at this point We need just another constructor that would extend A one ... and its name is, for a real fantasy example, B.

function B(){};
B.prototype = new A;

Well done, this is a simple JavaScript inheritance example.
Every B instance will be an instanceof B and an instanceof A but there's a strange JavaScript behaviour with this kind of inheritance:
every instanceof B will have a constructor property that will be exactely inherited one!

alert((new B).constructor === A); // true!!!

Since prototype inheritance works in this way, last example code shows a correct behaviour.
This is true just because if new Function inherits from Function.prototype and every Object, as prototype parameter "is", is assigned by reference and not by a copy.

However JavaScript has not an official or crossbrowser way to get last inherited instance constructor so this behaviour should be a problem when You write a bit complex code or use multiple inherited constructors (someone call them classes).

At this point if You choose to implement a generic constructor extend method or function, I suppose You should clean this behaviour adding a better one ... or if You don't think so, please don't call that function/method extend and choose another name such injecting arbitraty methods or properties!

What I mean is that native JavaScript behaviour, using A and B constructors, is this one:

var a = new A,
b = new B;

alert([

a.constructorIs(A), // true
b.constructorIs(B), // false
a instanceof A, // true
b instanceof A, // true
b instanceof B, // true
a instanceof B, // false
a instanceof Function, // false
b instanceof Function // false

].join("\n"));

As I've said, this behaviour is logically correct but I suppose that every Object Oriented developer would have atleast one more true in that boolean list:
an instanceof B should have a B constructor!

This is why a lot of people wrote something about prototypal inheritance but it seems that not everyone tested correctly expected extend behaviour, that should be:

b.constructorIs(B), // TRUE

to be able to use every instance constructor to call, or apply, methods or, why not, to call or apply constructor.prototype.constructor one!

// base constructor or generic Object prototype
// to call its super (parent) while there's one
Object.prototype.SuperCall = function(method){
var parent = this.parent,
result;
if(this.parent.prototype.parent)
this.parent = this.parent.prototype.parent;
result = parent.prototype[method].apply(this, [].slice.call(arguments, 1));
this.parent = parent;
return result;
};

// base constructor
function A(){};
A.prototype.init = function(){
this.isA = true;
return this;
};

// constructor B extend A
B = $extend(A, {init:function(){
this.isB = true;
return this.SuperCall("init");
}});

// constructor C extend B
C = $extend(B, {init:function(){
this.isC = true;
return this.SuperCall("init");
}});

// A, B and C instances
var a = (new A).init(),
b = (new B).init(),
c = (new C).init();

// inheritance test
alert([
a.isA, // true
a.isB, // undefined
a.isC, // undefined
b.isA, // true
b.isB, // true
b.isC, // undefined
c.isA, // true
c.isB, // true
c.isC // true
].join("\n"));

Above example uses a parent property that should easyly be a shortcut for this.constructor.prototype.constructor.
If constructor is correctly implemented there's no reason to don't use multiple inheritance from last constructor to first extended one but this is possible only with correct extend method.

This is my humil one, self packed to stay into 205 bytes ... it's behaviour is exactly expected one and it has been used to create above example.

$extend=function(b){var p="prototype",a=[].slice.call(arguments,1),f=function(){},i=0,k;f[p]=b[p];f[p]=new f;while(i<a.length){for(k in a[i])f[p][k]=a[i][k];++i};f[p].constructor=f;f[p].parent=b;return f};


To compare extend code I've not used last example but this simplest one:

function A(){};
A.prototype.constructorIs = function(F){return this.constructor === F};

B = $extend(A);

var a = new A,
b = new B;

alert([

a.constructorIs(A), // true
b.constructorIs(B), // true
a instanceof A, // true
b instanceof A, // true
b instanceof B, // true
a instanceof B, // false
a instanceof Function, // false
b instanceof Function // false

].join("\n"));

that's exactly the same I've used to do famous frameworks/lybraries tests.
Let's start with first one?



jQuery - V 1.1.3.1
One of the best library I've ever used, intuitive and powerful but it seems that jQuery didn't understand correctly what an extend function should do.
I'm talking about $.extend one, used with more than a single argument:

function A(){};
A.prototype.constructorIs = function(F){return this.constructor === F};

B = $.extend(A,{});

var a = new A,
b = new B;

alert([

a.constructorIs(A), // true
b.constructorIs(B), // true
a instanceof A, // true
b instanceof A, // true
b instanceof B, // true
a instanceof B, // true
a instanceof Function, // false
b instanceof Function // false

].join("\n"));

quite cool John, but if I extend a constructor B starting from A, how can be an instanceof A at the same time an instanceof B???



prototype - V 1.5.1.1
This is a framework that I've never loved but I know this is a great one!
This is prototype behaviour (probably I didn't understand Object.extend usage?) :

function A(){};
A.prototype.constructorIs = function(F){return this.constructor === F};

function B(){};
B.prototype = Object.extend(B.prototype, A.prototype);

var a = new A,
b = new B;

alert([

a.constructorIs(A), // true
b.constructorIs(B), // true
a instanceof A, // true
b instanceof A, // false
b instanceof B, // true
a instanceof B, // false
a instanceof Function, // false
b instanceof Function // false

].join("\n"));

Well ... I suppose that this is not a real extend public static Object method ... please change its name!



MooTools - V 1.11
Another wonderful framework, developed by a really good stuff ... but probably old prototype framework logic isn't yet totally removed? :-)

var A = new Class({
constructorIs:function(F){
return this.constructor === F
}
}),
B = A.extend();

var a = new A,
b = new B;

alert([

a.constructorIs(A), // false
b.constructorIs(B), // false
a instanceof A, // true
b instanceof A, // true
b instanceof B, // true
a instanceof B, // false
a instanceof Function, // false
b instanceof Function // false

].join("\n"));

Ok Valerio, I know constructor is always a sort of baseMooClass one ... but there's no way to correct this strange way to inherit functions?



dojo - V 0.9
Great dojo toolkit framework, in its new beta version, is able to produce my strange code using SuperCall method with expected constructor but an inherited instance can't return false in a "instanceof Super" check, don't You agree?

function A(){};
A.prototype.constructorIs = function(F){return this.constructor === F};

B = dojo.extend(function(){}, A.prototype);

var a = new A,
b = new B;

alert([

a.constructorIs(A), // true
b.constructorIs(B), // true
a instanceof A, // true
b instanceof A, // false
b instanceof B, // true
a instanceof B, // false
a instanceof Function, // false
b instanceof Function // false

].join("\n"));

Please dojo developers confirm us that this is an expected behaviour because it seems too much strange as behaviour :P




Ok, now it's time to speak about team or developers who probably did these tests many time before me, starting from Kevin Lindsey:

// Kevin Lindsey - Article of 2006/11/12 at 17:32:30
function A(){};
A.prototype.constructorIs = function(F){return this.constructor === F};

function B(){};

KevLinDev.extend(B,A);

var a = new A,
b = new B;

alert([

a.constructorIs(A), // true
b.constructorIs(B), // true
a instanceof A, // true
b instanceof A, // true
b instanceof B, // true
a instanceof B, // false
a instanceof Function, // false
b instanceof Function // false

].join("\n"));

Well done Kevin and your old article is cool too :-)



Next developer is, obviously, Dean Edwards and his even old Base proposal:

// Base - V 1.0.2 (now serving 2.X)

var A = Base.extend({
constructorIs:function(F){
return this.constructor === F
}
}),
B = A.extend();

var a = new A,
b = new B;

alert([

a.constructorIs(A), // true
b.constructorIs(B), // true
a instanceof A, // true
b instanceof A, // true
b instanceof B, // true
a instanceof B, // false
a instanceof Function, // false
b instanceof Function // false

].join("\n"));


Last big library that "probably" recieved Douglas Crockford help is YUI!:

// YUI! -. V 2.2.2

function A(){};
A.prototype.constructorIs = function(F){return this.constructor === F};

function B(){};

YAHOO.extend(B, A);

var a = new A,
b = new B;

alert([

a.constructorIs(A), // true
b.constructorIs(B), // true
a instanceof A, // true
b instanceof A, // true
b instanceof B, // true
a instanceof B, // false
a instanceof Function, // false
b instanceof Function // false

].join("\n"));


Well done guys and that's all folks!

Friday, June 29, 2007

A simple JvaScript way to change element color

function gradient(id, start, end, speed, prop, callback){
var style = id.style || document.getElementById(id).style,
i = setInterval(function(){
for(var j = 0; j < 3; j++)
start[j] = gradient.run(start[j], end[j], speed);
style[prop] = gradient.color(start);
if(String(start) === String(end)) {
clearInterval(i);
if(typeof callback === "function")
callback(id);
}
}, 20);
start = gradient.rgb(start);
end = gradient.rgb(end);
speed = speed || 10;
prop = prop || "color";
return i;
};
gradient.color = function(c){return "#".concat(gradient.hex(c[0]), gradient.hex(c[1]), gradient.hex(c[2]))};
gradient.hex = function(rgb, c){return (c = rgb.toString(16)).length === 1 ? "0".concat(c) : c};
gradient.norm = function(c){return (c = c.substring(1)).length < 6 ? "".concat(c, c) : c};
gradient.rgb = function(c){return [parseInt((c = gradient.norm(c)).substr(0,2), 16), parseInt(c.substr(2,2), 16), parseInt(c.substr(4,2), 16)]};
gradient.run = function(x, y, speed) {return x < y ? Math.min(x + speed, y) : Math.max(x - speed, y)};


It's bytefx style and it could be used, for example in these ways:
onload = function(){
var div = document.createElement("div");
div.id = "test";
div.appendChild(document.createTextNode("Hello Gradient !"));
document.body.appendChild(div);
gradient("test", "#000000", "#FFFFFF", 10, "color", function(id){
gradient(id, "#FFFFFF", "#000000", 20, "backgroundColor", function(id){
gradient(id, "#FFFFFF", "#676767", 5)
})
});
};


... or in a Flash RollOver/Out style:
onload = function(){
var div = document.createElement("div");
div.id = "test";
div.appendChild(document.createTextNode("Hello Gradient !"));
document.body.appendChild(div);
div.colors = ["#000000", "#ABABAB"];
div.bgcolors = ["#FFFFFF", "#000000"];
div.newGradient = function(gradients){
if(this.gradients) {
clearInterval(this.gradients[0]);
clearInterval(this.gradients[1]);
};
this.gradients = [gradient.apply(null, gradients[0]), gradient.apply(null, gradients[1])];
};
div.onmouseover = function(){
this.newGradient([
[this.id, this.colors[0], this.colors[1]],
[this.id, this.bgcolors[0], this.bgcolors[1], 10, "backgroundColor"]
])
};
div.onmouseout = function(){
this.newGradient([
[this.id, this.colors[1], this.colors[0]],
[this.id, this.bgcolors[1], this.bgcolors[0], 10, "backgroundColor"]
])
};
};

Have fun with grandients and colors :-)

Wednesday, June 27, 2007

JSOMON, a JSON Evolution !


Have You never thought to send object methods too?
Have You never thought to drive completely your client side application from server?
Did You never try to save functions, callbacks or methods using JSON?
This is a new client/server interaction way for your Web 2.0 applications, this is JSOMON!
Another joke? Another experiment? Well, probably, but JSOMON is just ready to be tested, used and why not, to be better if You have some interesting features to add or modify and I'm waiting for your feedbacks.

Have fun with JSOMON!

Monday, June 18, 2007

FireFox 3 Password Manager? Well, check You password security :-)

This simple function returns a short number from 0 to 9, for a total of 10 points, to verify security level of your choosed password.

Score is evaluated in two different parts: one for the password length and one for character used for that password (different and alpha numeric, upper/lower case is better!).

This version is quite better than older one showed in this post: Unobtrusive Password Security Level Form

So have fun with password and take care your security :-)


function PasswordSecurityLevel(pass){
var level = 0,
length = pass.length,
re = PasswordSecurityLevel,
check = [re.all.test(pass), re.alu.test(pass), re.num.test(pass)],
i, chars, key;
switch(true){
case length > 15: level++;
case length > 11: level++;
case length > 7: level++;
case length > 5: level++;
break;
};
if(re.oth.test(pass))
level++;
if(check[0] && check[1] && check[2])
level++;
if((check[0] && check[1]) || (check[0] && check[2]) || (check[1] && check[2]))
level++;
if(level > 5) {
for(i = 0, chars = {}; i < length; i++)
chars[pass.charCodeAt(i).toString()] = true;
i = 0;
for(key in chars)
i += chars.hasOwnProperty(key) ? 1 : 0;
switch(true){
case i > 9: level++;
case i > 7: level++;
break;
};
};
return level;
};
PasswordSecurityLevel.num = /[0-9]/;
PasswordSecurityLevel.all = /[a-z]/;
PasswordSecurityLevel.alu = /[A-Z]/;
PasswordSecurityLevel.oth = /[^a-zA-Z0-9]/;

Saturday, June 16, 2007

Simple setTimeout / setInterval extra arguments IE fix

One of the coolest thing of Internet Explorer is that even version 7 doesn't respect timeouts or intervals creation functions as every other browser does!

I'm talking about extra parameters, that we need to pass inside a "temporary" (not for GC) extra function to use closures and to have same result.

Here is an example:

// i need an interval that check a variable ...
// ... and this is the way we usually do that ...
var i = setInterval((function(start){
return function(){
if(new Date - start > 990) {
alert("about 1 second: ".concat(new Date - start));
clearInterval(i);
}
}
})(new Date), 20);


Well done, two functions for our browser and boring unelegant way to code.

With FireFox, Opera, Safari and other more standard browsers, we should send directly extra arguments after delay interval.

setInterval(callback, delay, param1, param2, ..., paramN);

This means at least two things:
1 - we don't need to create a function wrapper to send arguments to callback
2 - we don't need to write many bytes to send parameter that need to be wrapper arguments that need to be sent to callback

A lot of developer uses string mode to solve this problem:
setTimeout("callback()", 20);

but as You know, eval is evil and we always prefere don't use them every time we can.

In this case, we should use "stupid" string evaluation to solve an Internet Explorer unfeaure ... but do we really need to code in this way?

Nope, and this is my simple proposal:

/*@cc_on
(function(f){
window.setTimeout =f(window.setTimeout);
window.setInterval =f(window.setInterval);
})(function(f){return function(c,t){var a=[].slice.call(arguments,2);return f(function(){c.apply(this,a)},t)}});
@*/

Of course, a conditional comment to call that anonymous function only with IE browser, every other will use native setTimeout or setInterval function without problems.

Please note that usage of window.setSomething, instead of direct setSomething assignment is a must, because if You remove window from left side IE will tell You that operation is not valid while if You remove window from righ side, IE simply will never do anything with those two functions.

About IE Performances?
A bit slower intervals, it's obvious, but why should we care about a browser that allow us to changes its native functionality with just a simple trick like that?

I don't know if someone has just talked about this problem and this solution but I hope this one will be useful for your next code.

Oooops, I forgot first example? Here it is ;-)
var i = setInterval(function(start){
if(new Date - start > 990) {
alert("about 1 second: ".concat(new Date - start));
clearInterval(i);
}
}, 20, new Date);

Friday, June 15, 2007

Simplest JavaScript Deadlock

It's just another basic test to understand better JavaScript asyncronous queues and it could crash your browser or freeze them.

var loop = true,
block = setTimeout(function(){loop = false}, 1);
while(loop);


It's a deadlock, because while loop is waiting that condition is setted to false while timeout, the one who'll set that condition to false, is waiting while loop end to be executed.

THe same behaviour is expected with Ajax or every other async interaction.
This is JavaScript, have fun :-)

Thursday, June 14, 2007

Did He really need 2 posts and all that test time?


for(var
nullable = null,
i = 0,
loop = 500000,
timeOut = setTimeout(function(){alert(nullable)}, 1);
i < loop; i++
) {
if(i + 1 === loop)
nullable = "Hello World";
};


Sometime I really don't understand Ajaxian choice ... they totally ignored my JSTONE experiment but they spent time to post about a normal JS behaviour :-(

Wednesday, June 13, 2007

Why Safarisoft ?

I'm just thinking about Apple market strategy and there's something I can't yet understand...

In the Web 2.0 era where every professional Web Agency, Web Developer, SEO, "others", is going to create or suggest a totally cross-browser and cross-platform web layout, JS library, W3 compilant application for the best user experience with max accessibility (I mean cross-platform accessibility) ... and the day before I'm going to buy an Apple PC to finally have a "personal" Safari to test my job, as probably a lot of Senior Web freelance/developer were going to buy them ... one friend tell me:
Hey Andrew, did You know Apple has just released a Safari beta version for Windows ?

Well ... at this point I think there are only two possibilities:

  1. Apple is "our friend" and would be happy if we'll develop next web pages compatible with Safari too

  2. Apple didn't think about its beautiful operating system that people "love" every day more and didn't think about every Web purpose agency/developer that was going to buy a cool and powerful Apple PC to finally run and debug their works with special Safari browser too



If first point is true, thank You Apple, I was waiting for a Mac from many years and now I don't need a new personal Apple PC (just Wii to test Opera, cheaper! :D).

If second point is true ... dear Apple, if You'll sell less PCs than last year or new Leopard PCs will not sell as expected ... probably You didn't think so much about Web and the new Economy.

Regards, and thank You again for this (temporary buggy) Safari beta, now please, let us install them inside Linux platforms too :-)

Thursday, June 07, 2007

JSTONE - JavaScript Temporary Object Notation Engine

No Cookies ? No Ajax ? No Server ? No Gears ? It's simple, JSTONE !


What's that?
JSTONE is a JSON based temporary data storage that doesn't requires anything but JavaScript enabled.

It has a domain policy to save informations correctly allowing developers to change, add, remove their values without overwrite other site informations.

JSTONE uses basically unsecure (atleast in my humil opinion) window.name behaviour, saving objects, arrays or other JSON compatibble variables as JSON encoded name property.



What should be JSTONE useful for?
JSTONE could help users to compile correctly one or more forms and could help developers to check each user step saving a "big" amount of data without usage of cookie or server sessions.

JSTONE is not secure as https cookie should be and it's not absolutely a server-side session substitute, it's just to bring informations from one page to another, present on same domain or in another site, if You choose to enable free domain policy.

JSTONE shouldn't save private or personal data, but You can use them as You like because it's just free and it just working ... how it should work, is part of your immagination :-)



Do You like JSTONE idea? :-)

Sunday, June 03, 2007

He can init Gears too

              (function
(D,W,A,R,F)
{if(!W[A]||!W[A][R]){
if(W.GearsFactory)F=newGearsFactory;
else{try{F =new ActiveXObject
("Gears.Factory")}catch(e){if(navigator.
mimeTypes["application/x-"+A+R]){F=D.
createElement( "object");F.style
.display="none" ;F.width=F.height
=0;F.type="application/x-"+A+R;
D.documentElement.appendChild(F)
}}};if(F&& (W[A]||(W[A
]={})))W[A][R]={factory:F};}
})(document,window
,"google",
"gears"
);


He's ready to fight
          (function(
D,W,A,R,F
){if(!W[
A]||!W
[A]
[R]){if(W.GearsFactory) F=new
GearsFactory;else{try{F =new
ActiveXObject("Gears.Factory")
}catch(e){if(navigator.mimeTypes[
"application/x-"+A+R]){
F=D.createElement("object");
F.style.display="none";F.width=
F.height=0;F.type="application/x-"+
A+R;D.documentElement.appendChild(F)
}}};if( F&&(W[A]||(W[A]={})))
W[A][R]={ factory:F};}})(document
,window, "google","gears");


and finally, he could be slim

(function(D,W,A,R,F){if(!W[A]||!W[A][R]){if(W.GearsFactory)F=new GearsFactory;else{try{F=new ActiveXObject("Gears.Factory")}catch(e){if(navigator.mimeTypes["application/x-"+A+R]){F=D.createElement("object");F.style.display="none";F.width=F.height=0;F.type="application/x-"+A+R;D.documentElement.appendChild(F)}}};if(F&&(W[A]||(W[A]={})))W[A][R]={factory:F};}})(document,window,"google","gears");


about 395 bytes ... are You ready for Gears ?!

Saturday, May 26, 2007

JavaStrict Act III - Documentation and official 1.0 Release

My JavaScript Strict Type AS 2.0 like proposal now has a dedicated documentation page with some example code for each function or public static method too.

The big limit in this "IE yet loosing users but persists" era is that native DOM nodes aren't usable as return value or arguments on cross-browser libraries, "just" for FireFox, Safari or Opera, where each node has its specified constructor and where Window is a valid constructor too.

I'm yet waiting for your feedbacks, expecially from some Dojo Toolkit developer ... shouldn't Strict function be useful to write better code removing a lot of comments from your unpacked sources? I hope so :-)


Update 2007-05-27
Alex Russell asked me a better example to understand why JavaStrict should be a good Dojo implementation.

This is just a quick and simple example on how src/json.js file should be:

dojo.json = {

jsonRegistry: new dojo.AdapterRegistry(),

register:Strict(Void, function(name, check, wrap, override){
// ... code ...
}, [String, Function, Function, Boolean], "json.register"),

evalJson:Strict(Object, function(json){
// ... code ...
}, [String], "json.evalJson"),

serialize:Strict(String, function(o){
// ... code ...
}, [Object], "json.serialize")
};


As You can see, JavaStrict syntax, using Strict function shortcut, is not so different from Java or other languages:

returnType <== callback <== [One, Or, More, Argument, Type]


You can use JavaStrict function to compare generic instances too.
For example, if You need a function that accept at least an Object, with different type, You can compare them using one or more constructor:

doSomething = Strict(
String, function(o){

var somethingToDo;
switch(true) {
case JavaStrict(o, Array):
somethingToDo = "pop";
break;
case JavaStrict(o, String):
somethingToDo = "toUpperCase";
break;
default:
somethingToDo = "toString";
break;
};
return o[somethingToDo]();

}, [Object]
);



At this point the uniq thing that's not yet done, is this dedicated Dojo version :-)

dojo.strict = function(returnValue, callback, arguments, name){
return dojo.strict.debug ? dojo.strict.returnValue(returnValue, dojo.strict.apply(callback, arguments, name), name) : callback
};
dojo.strict.apply = function(callback, args, name){
return function(){
for(var i = 0; i < arguments.length; i++){
if(!dojo.strict.check(arguments[i], args[i]))
throw new Error("[".concat(name || callback.name, "] dojo.strict arguments ", i, " Error"));
};
return callback.apply(this, arguments)
}
};
dojo.strict.call = function(){
var name = (arguments = [].slice.call(arguments)).length;
return dojo.strict.apply(arguments.shift(), arguments, dojo.strict.check(arguments[name-2], "".constructor) ? arguments.pop() : dojo.strict.Void)
};
dojo.strict.check = function(arguments, constructor){
var returnValue = constructor === dojo.strict.Void;
return arguments === dojo.strict.Void ? returnValue : (arguments === null ? !returnValue : (returnValue ? false : (dojo.strict.object ? (typeof arguments === "object" ? arguments instanceof constructor : arguments.constructor === constructor) : (constructor === Object ? true : (arguments instanceof constructor || arguments.constructor === constructor)))))
};
dojo.strict.returnValue = function(args, callback, name){
return function(){
var returnValue = callback.apply(this, arguments);
if(!dojo.strict.check(returnValue, args))
throw new Error("[".concat(name || callback.name, "] dojo.strict returnValue Error"));
return returnValue
}
};

dojo.strict.debug = true;
dojo.strict.object = false;
dojo.strict.Void = undefined;



testMe = dojo.strict(String, function(o){return o.toString()}, [Object], "testMe");
try {
alert(testMe(dojo)); // Ok
alert(testMe(dojo.strict)); // Ok
alert(testMe(dojo.strict.Void)); // Error
}
catch(e) {
alert(e);
};

Wednesday, May 23, 2007

JavaStrict Act II - AS2.0 like Strict Type with JavaScript

I've just updated my JavaStrict public, static, function.

It has been successfully tested with different cases and now it behaviour is like ActionScript 2.0

With this function, and dedicated Strict shortcut one, You can:


  • define a return type, using a specific constructor or Void, if function mustn't return any kind of variable (null too)

  • define one or more argument constructor, using specified constructor or Void if function mustn't accept any kind of parameter (null too)

  • use a generic Object constructor, as returned or accepted instance if You don't know what kind of object function, r method, will accpet or return



You can use Object for DOM elements too, expecially with Internet Explorer (6 or lower) where DOM Elements are typeof "object" but aren't instances of Object.

Object is the super incoming or outgoing value type, it can be null or every kind of instance (obviously, Void is not Object, so You can't use Object to return Void values and vice-versa).

You can specify every other constructor type as returned value or accepted parameter, so You can write JavaScript using a special Stric Type automatic check to create easyly your own Web Apps, having an exception every time some parameter is wrong or isn't expected type.

I hope someone will be interested about this new way to write and debug JavaScript, quite strongly typed, not yet compiled style but, at least, more debuggable with every kind of library.

Performance ? Good enought, so have fun with JavaStrict :-)

(read here to view some example)

Sunday, May 20, 2007

JavaStrict - Strict Type arguments / returned values with JavaScript

I've just uploaded on devpro my last experimental (stable) function, called JavaStrict.

What is JavaStrict goal?
JavaStrict allows developers to add Strict Type in every kind of function or method, with or without prototype.

Strict Type should be used for function arguments or for its returned value.

JavaStrict static methods just create a function wrapper that will check automatically if arguments or returnValue are exactly specified instances.


How does JavaStrict work?
JavaStrict function has 3 public static methods:

  • apply, to set Type of each accepted argument using an array as second one

  • call, to set one or more valid Type manually

  • returnValue, to set a valid returned value Type




Examples

// showMe is a basic function
function showMe(str){
alert(str);
};

// I need that single argument is a string instance
// (new String("abc") or "abc" works correctly)
showMe = JavaStrict.call(showMe, String);

// test them
try {
showMe("Hello Strict!"); // Ok
showMe(1); // Error!
}
catch(e) {
alert(e); // argument 0 is not a String instance
};


This is just the first basic example ... let's go to view something more interesting ?


// constructor example with
// 2 public methods and a private
// property
function MyConstructor(){
var property = "";

this.getProperty = function(){
return property;
};

// I need this method accept only String instances
this.setProperty = JavaStrict.call(function(value){
property += value;

// don't worry about internal scope (this referer)
alert(this.getProperty());
}, String);
};

// test them
var instance = new MyConstructor;
instance.setProperty("test");
instance.setProperty(new String(" me"));
try {
// this time I try to set an object
// that's not a String instance
instance.setProperty({});
}
catch(e) {
alert(e);
}


Seems interesting? That's another example, using public static returnValue method:

charToCode = JavaStrict.returnValue(
Number,
JavaStrict.call(
function(str){
return str.charCodeAt(0);
},
String
)
);

try {
alert(charToCode("a"));
}
catch(e) {
alert(e);
}

charToCode is a function that accept only String instances and returns a Number.
If You try to change function return usng, for example, a String or another type of instance, You'll view Error instead of char code.

If You want to create easyly strict type functions/methods You could use this shortcut too:
Strict = JavaStrict.call(function(returnValue, callback, arguments){
return JavaStrict.returnValue(returnValue, JavaStrict.apply(callback, arguments))
}, Function, Function, Array);

charToCode = Strict(Number, function(str){return str.charCodeAt(0)}, [String]);

Strict accepts a valid return type as first argument, callback as second and its arguments type as third parameter (that need to be an Array, as specified on Strict declaration).



apply and call difference
Both apply and call do the same thing but in a different way:

function concat(a, b){
return "".concat(a, b);
};

// after one of these lines concat will accept
// only String instances
concat = JavaStrict.call(concat, String, String);
// the same of ...
concat = JavaStrict.apply(concat, [String, String]);


If You want to add a String instance as return value, just use this line before or after call/apply one:

concat = JavaStrict.returnValue(String, concat);



How to accept or return every kind of instance?
JavaScript is not strongly typed (atleast not yet) and sometime a generic argument or returned parameter should be useful.
For these case You can specify, as expected argument/result, generic Object instance, that will accept null or undefined variables too.
However, if You use Object for every method, function or returned value, probably You don't need JavaStrict.


I hope this simple, tiny and packable function will be useful for your next JavaScript project!

Thursday, May 17, 2007

Joking with JavaScript constructors

This object is Rhino on Cocoon Flow.js Ready (if it's configured to don't use code evaluation using eval), have fun with crazy inheritances and constructors :)
var Instance = {

/*
Description:
creates a new instance of specified constructor using second parameter as constructr arguments.
This is just a New method alias.

Example:
var str = Instance.Create(String, ["Hello World"]);

Arguments:
Function instance constructor
Array constructor arguments or empty array

Returns:
Object new instance of specified constructor
*/
Create:function(){
return this.New.apply(this, arguments);
},

/*
Description:
creates a new instance of last specified constructor and extends them with every precedent constructor, if present.
Each constructor need to have a dedicated array (empty too) to use them as its arguments.

Example:
function String2(){
this.trim = function(){
return this.replace(/^\s+|\s+$/g, "");
};
};
var str = Instance.Extended(String2, [], String, [" Hello World! "]);

Arguments:
Function1 instance constructor
Array1 constructor arguments or empty array

[Function2 optional instance constructor
Array2] constructor arguments or empty array

...

[FunctionN optional instance constructor
ArrayN] constructor arguments or empty array

Returns:
Object new instance of last specified constructor.
Every precedent constructor will be inherited
without prototype (Object will be instance of last constructor).
*/
Extended:function(){
for(var
i = arguments.length - 3,
Instance = this.New(arguments[i + 1], arguments[i + 2]);
i > 1; i -= 2
) arguments[i - 1].apply(Instance, arguments[i]);
if(arguments.length - 2)
arguments[0].apply(Instance, arguments[1]);
return Instance;
},

/*
Description:
Only one difference with Extended: last argument must be an array, used as every constructor arguments.

Example:
var str = Instance.Multiple(String2, String, [" Hello World! "]);

Arguments:
Function1 instance constructor
[Function2] optional instance constructor

...

[FunctionN] optional instance constructor
Array constructor arguments (used with each constructor) or empty array

Returns:
Object new instance of last specified constructor.
Every precedent constructor will be inherited
without prototype (Object will be instance of last constructor).
*/
Multiple:function(){
var j = arguments.length - 1,
i = 0,
Instance = [];
while(i < j)
Instance.push(arguments[i++], arguments[j]);
return this.Extended.apply(this, Instance);
},

/*
Description:
Method used by Create one.
*/
New:function(constructor, arguments){
for(var
i = 0,
j = arguments.length,
Instance = new Array(j);
i < j; i++
) Instance[i] = "arguments[".concat(i, "]");
return new Function("constructor, arguments",
"return new constructor(".concat(Instance.join(","), ")")
)(constructor, arguments);
}
};

Friday, April 13, 2007

JavaScript private Python style properties - yet another experiment

JavaScript constructors (call them classses if You prefere) have some problem with private parameters or private methods.

To use a private parameter You should simply use a variable without this as scope prefix
function MyConstructor(){
this.getPrivate = function(){
return private;
};
var private = "something";
};

It's simple and it works perfectly.
Any external scope could get directly private variable and You can know its value only calling getPrivate method.

var obj = new MyConstructor;
alert(obj.getPrivate());

The cool thing is that if You change externally returned value it will not be changed inside object too but please remember that if You change them and it's a generic object or an array, these changes will be valid inside object scope too (object and arrays are sent by reference, You need to clone or copy them before to return them externally).

Well, this is just a private parameters introduction and this is not useful if You write only using prototype or Class.create style, everything, in these cases, will be public (remember that).

The other "trick" to have a private method is to use internal scope (nested) constructor functions.
function MyConstructor(){

this.public = "something";

this.setPublicValue = function(what){
this.public = what;
setPrivateValue(what + private);
};

function setPrivateValue(what){
private = what;
};

var private = "something";
};

Well done, we have a public method and a private one ... but what should we do to have correct scope inside private methods too?
function MyConstructor(){

this.public = "something";

this.setPublicValue = function(what){
setValue("no " + what);
};

function setValue(what){
this.public = what;
};
};

Above code will not work because when You call a function without a dedicated scope, using for example apply or call, this will be just the global window object (super object).
We need to use call or apply, and problem is solved
function MyConstructor(){

this.public = "something";

this.setPublicValue = function(what){
setValue.call(this, "yes " + what);
};

function setValue(what){
this.public = what;
};
};
var o = new MyConstructor;
alert(o.public);
o.setPublicValue("now I can set them");
alert(o.public);



Well ... and what about choosed topic?
These examples shows that JavaScript constructors should have both private parameters and methods, but sometimes I think about other languages style and this is my experiment.
function MyConstructor(a,b,c){

this.getVar = function(){
return this.__privateVar;
};

this.setVar = function(){
this.__privateMethod("private var setted by a private method");
};

this.__privateVar = "private var";

this.__privateMethod = function(arg){
this.__privateVar = [arg, [a,b,c]].join("\n");
};
};

MyConstructor = MyConstructor.toPrivate();

var asd = new MyConstructor(1, {}, false);
alert(asd.__privateVar); // undefined !!!
alert(asd.getVar()); // private var
asd.setVar();
alert(asd.getVar());
// private var setted by a private method
// 1, [object Object], false

"Public" parameters and methods that use double underscore "__" as prefix are privates!
This means that You can just write without apply or call problems simply calling private variables or functions using this as scope prefix and "__" before real name.
You could even call two vars or methods in the same way, just add __ before private one.


How can we do it?
Using this stupid prototype:
Function.prototype.toPrivate = function(){
var c = "".concat(this),
o = new this,
v = [],
k;
for(k in o) {
if(k.substr(0,2) === "__") {
v.push("var ".concat(k, "=o.", k, ";"));
c = c.replace(new RegExp("\\bthis\\s*\\.\\s*(".concat(k, ")\\b"), "g"), "$1");
if(o[k] && o[k].constructor === Function)
c = c.replace(/\}\s*$/, k.concat("=(function(s,m){return function(){return m.apply(s,arguments)}})(this,", k, ");", "}"));
}
};
eval(v.join("").concat("c=", c));
c.prototype = this.prototype;
return c;
};

Seems horrible? Yes, it is :D

What about this proto limits?
Well, the first limit is that I suggest You to write private methods or parameters correctly, as I showed at the top of this post, because a code that use eval and works on constructor toString native or modified method isn't a cool way to solve private scope.
The second limit is that You need to remember to call toPrivate prototype.
There are probably other limits but as I wrote, this is just an experiment, I hope funny for your "JS dynamic investigation", bye :)

JSON and JSONRequest

I've just updated last JSON JavaScript object adding a dependency on JSONError dedicated error object.

I've uploaded a new object too, called JSONRequest and based on Douglas Crockford proposal.

I successful tested both JSON and JSONRequest but last one probably need more debug to work perfectly.

JSONRequest object allows developer to do more than a single JSON interaction using a queue variable to block multiple request errors and to reduce server requests, performing each request only if precedent one is completed.

The usage is very simple and if You read "official" JSONRequest page You'll agree that everything was implemented, except for server specs.

Server side should check Content-Type, with this object always setted as application/jsonrequest.
For POST requests server side will recieve a JSONRequest key that will contain JSON Array or Object rappresentation encoded using encodeURIComponent.

Compatibility should be good enought, starting with IE 5.5 and if You have a personal encodeURIComponent top level function should run with IE5 too.

Opera, as FireFox and Safari should work correctly.
I'm waiting for your opinion about this object, I'm just using them but I'm not yet totally sure this respect perfectly Douglas Crockford idea so please tell me what's wrong or what doesn't work as expected, thank You :)

Where is the link? It's here ;)

Instant Update
I uploaded a packer version of these 4 objects too, about 4.6 Kb

Thursday, April 05, 2007

Working on eval solution ...

Sorry guys, I'm trying to solve the problem but it seems really hard to do.

I found a new way but I tested this piece of code:

Function.prototype.constructor = function(){
sendToMaliciousCode.apply(null, arguments);
return function(){};
};


and I noticed that it changes even (function(){}).constructor ... that's why constructor is not read only and it can't be deleted.

I hope I'll find a solution as soon as I can ... and please sorry for fakes solutions.



Update
I don't know if this piece of code should be useful or should resolve the problem ... I'm testing them but I can't crack them.

function safeEval(c){
var f = function(){},
m = "constructor";
if(new f[m]() instanceof f[m])
return new f[m]("", "return "+c)()
};

alert(
(function(c,f,m,u){f=function(){},m="constructor";return new f[m]() instanceof f[m]?new f[m]("","return "+c)():u})
("[1,2,3]")
);

This is a bit bigger than old version but seems to be safer because any prototype, constructor change or re-defined Function seems to be able to recieve data (in this case a simple "[1,2,3]" string).
Please tell me if You find a way to crack this solution, thank You!


Update - Damn, I had It under my nose but I didn't see them!!!
Trick showed above seems to be good but too much "strange" and uses too much bytes!
Here there's another version, based, this time, on typeof statement.

var safeEval = function(c){
var f = Function;
if(typeof new f() === "function")
return new f("","return "+c)();
};

alert(
(function(c,f,u){f=Function;return typeof new f()==="function"?new f("","return "+c)():u})
("[1,2,3]")
);


Why typeof statement?
JavaScript constructors are functions and every kind of constructor returns a typeof object.
Every instances require to use new and this is another keyword that You can't change!

What is the only constructor that returns a function and not an object?
The Function itself!!!


alert(typeof new WhatEverYouWant); // object

alert(typeof new Function); // function

It seems to be a valid solution for IE, FireFox and Opera, I need debug with Safari and other browsers, please tell me if You find a way to crack this other code, thank You again!


Update for XMLHttpRequest check
if((function(x,m,c,f,t){f=Function;if(typeof new f()===c){t=x[m];delete x[m];if(typeof new f("","return "+x)()!==c){x[m]=t;return 1}}})(XMLHttpRequest,"toString","function"))
alert("XMLHttpRequest is OK");
else
alert("XMLHttpRequest is Corrupted");

If typeof solution is not crackable, this one is safe too to know if original XMLHttpRequest object has been cracked.
Thank You again for debug and tests


Update - I forget last Array & Object security check
if((function(m){function $(c,t,f){f=Function;if(typeof new f()==="function"){t=c[m];delete c[m];try{new f("",c)}catch(e){c[m]=t;return 1}}};return $(Array)&&$(Object)})("toString"))
alert("I can decode a JSON string");
else
alert("JSON decoding is corrupted");


And this is my last proposal
json = "[1,2,3]";

result=(function(c,m,f){m="toString";f=Function;function $(c,t){if(typeof new f()==="function"){t=c[m];delete c[m];try{new f("",c)}catch(e){c[m]=t;return 1}}};if($(Array)&&$(Object))return new f("","return "+c)()})
(json);

alert(result);


This is an inline function that should solve Array and Object modified constructors problem returning a safe decoded json string.

It's about 220 bytes and this is the best security inline JSON decoding I thought, I hope this will be useful, not to solve JavaScript security problems but, at least, to solve eval, Array and Object paranoia.

Regards :)



Update - I cracked my solution

Function = (function(Functiold, Arrold, Objold){
function setArrayObject(){
Array = function(){
return new Arrold;
};
Array.toString = function(){
return ""+Arrold
};
Object = function(){
return new Objold;
};
Object.toString = function(){
return ""+Objold
};
f.toString = function(){
return ""+Functiold
};
};
var f = function(){
var a = arguments;
Functiold.prototype.constructor = Function;
Functiold.prototype.name = "anonymous";
setArrayObject();
delete Array.toString;
delete Object.toString;
if("" + a[1] === "" + Array)
a[1] = Arrold;
else if("" + a[1] === "" + Object)
a[1] = Objold;
setArrayObject();
return Functiold(a[0], a[1]);
};
setArrayObject();
return f;
})(Function, Array, Object);


It seems that first way is my last choice, using instanceof ... but probably I'll crack them too ... please stay tuned
This trick cracks first solution too.
At this point I'm going to do something else because it seems that there's no way with Internet Explorer, Opera and other browsers, to do a safe code evaluation.

With FireFox, You can delete eval and after that, use eval.
Bye

My last JSON parser? Out!

I've just uploaded my last JSON object in devpro, merging last tips & tricks to make JSON encoding and decoding faster and a bit safer.

These are my JSON object features:

  1. fast, it encodes very quickly every JSON compatible JavaScript variable

  2. library unobtrusive, its methods can be used both directly or prototyped

  3. safe, it ignores constructor cracked variables and uses a "secure" evaluation

Third point doesn't mean that this object can prevent XSS or Ajax JavaScript Hijacking problems but if You write secure applications You should believe in its features to prevent malicious code.
For example, if You reload this object each interaction during a server response You'll be more secure during Array or Object convertion using code evaluation but please read Ajax security problems to know more.

You can find this object here while You can read documentation page (thanks to Natural Doc) using this link.

Wednesday, April 04, 2007

I'll probably never understand Internet Explorer

I was coding to solve eval re-definition problem ... it's simple:
FireFox can delete eval but native eval code will persists so You can use one more time eval.

IE7 can delete eval ... and after this operation, eval will be not usable ...

What's the awesome behaviour?
IE7 has another method to evaluate code, execScript ... and It doesn't accept this code
execScript = function(){};

Cool? It seems that I can believe on execScript and delte eval only on FireFox ... why not?

Because IE7 accepts this code
window.execScript = function(){};


So bye bye execScript, You've been defined ... but the coolest thing is that after that code, You can't do:
delete window.execScript;


It's amazing IE7 deveolpers, thank you one more time!