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);
};