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

Monday, December 27, 2010

ES5 Common Design Patterns Examples - Part 1


// Abstract Factory
/*
({}).createInstance()

(function (a, b, c) {
this.sum = a + b + c;
}).createInstance([1, 2, 3])

*/
Object.defineProperty(
// (C) WebReflection - Mit Style License
Object.prototype,
"createInstance",
{
value: (function (create) {
return function createInstance(args) {
var
self = this,
isFunction = typeof self == "function",
obj = create(isFunction ? self.prototype : self)
;
isFunction && args != null && self.apply(obj, args);
return obj;
};
}(Object.create))
}
);

// Abstract Builder
/*
var person = Object.builder({
setup: function (name) {
this.create();
this.instance.name = name;
}
});
person.setup("WebReflection");
alert(person.instance.name);
person.create();
person.instance.name = "Andrea";
alert(person.instance.name);
*/
Object.defineProperty(
// (C) WebReflection - Mit Style License
Function.prototype,
"builder",
{
value: function (methods) {
var
$create = Object.create,
self = this,
proto = self.prototype,
obj
;
return $create(methods, {
instance: {
get: function get() {
return obj;
}
},
create: {
value: function create() {
obj = $create(proto);
self.apply(obj, arguments);
}
}
});
}
}
);

// Multiton + Singleton pattern
// (via lazy initialization)
/*
function Car(){}
var car = Car.getInstance();
alert(car === Car.getInstance());
alert(car !== Car.getInstance("bmw"));
alert(Car.getInstance("bmw") === Car.getInstance("bmw"));
*/
Object.defineProperty(
// (C) WebReflection - Mit Style License
Function.prototype,
"getInstance",
{
value: function (key) {
var
create = Object.create,
instances = {},
self = this,
proto = self.prototype,
instance
;
Object.defineProperty(
self,
"getInstance",
{
value: function getInstance(key) {
return key == null ?
instance || (instance = create(proto)) :
instances.hasOwnProperty(key) ?
instances[key] :
instances[key] = create(proto)
;
}
}
);
return self.getInstance(key);
}
}
);

// Prototype
/*
var definition = {some:"thing"};
var inherited = Object.create(definition);
*/
Object.create;

// Abstract Adapter
/*
function Person() {}
Person.prototype.setName = function setName(_name) {
this._name = _name;
};

var getter = {
toString: function () {
return this._name;
}
};

var me = {};
me.adapt(Person);
me.setName("WebReflection");
me.adapt(getter);
alert(me);
*/
Object.defineProperty(
// (C) WebReflection - Mit Style License
Object.prototype,
"adapt",
{
value: (function (proto) {
return proto in {} ?
function adapt(Class) {
this[proto] = typeof Class == "function" ? Class.prototype : Class;
} :
function adapt(Class) {
var self = this;
typeof Class == "function" && Class = Class.prototype;
for (proto in Class)
self.hasOwnProperty(proto) || (self[proto] = Class[proto])
;
}
;
}("__proto__"))
}
);

// Abstract Composite
/*
function AddToBody(value) {
this.value = value;
}
AddToBody.prototype.value = "";
AddToBody.prototype.exec = function () {
document.body.appendChild(
document.createElement("p")
).innerHTML = this.value;
};

var many = AddToBody.composite();
many.push(
new AddToBody("this"),
new AddToBody("is"),
new AddToBody("a"),
new AddToBody("test")
);

this.onload = function () {
many.exec();
alert(many.value);
many.value = "everybody like this";
many.exec();
alert(many.value);
};
*/
Object.defineProperty(
// (C) WebReflection - Mit Style License
Function.prototype,
"composite",
{
value: (function (defineProperty) {
return function composite() {
function get(key) {
function retrieve(item) {
return item[key];
}
return function get() {
return map.call(this, retrieve);
};
}
function set(key) {
function assign(item) {
item[key] = this;
}
return function set(value) {
forEach.call(this, assign, value);
};
}
function wrap(method) {
function apply(item) {
method.apply(item, this);
}
return function wrap() {
forEach.call(this, apply, arguments);
};
}
var
composite = [],
forEach = composite.forEach,
map = composite.map,
proto = this.prototype,
key, value
;
for (key in proto) {
if (typeof(value = proto[key]) == "function") {
composite[key] = wrap(value);
} else {
defineProperty(
composite,
key,
{
get: get(key),
set: set(key)
}
);
}
}
return composite;
};
}(Object.defineProperty))
}
);

// Observer/Listener
/*
function hello(e) {
alert(e.type);
}
var obj = new Listener;
obj.addEvent("hello", hello);
obj.addEvent("hello", hello);
obj.fireEvent("hello");
obj.fireEvent({type:"hello"});
obj.removeEvent("hello", hello);
obj.fireEvent({type:"hello"});
*/
var Listener = (function () {
// (C) WebReflection - Mit Style License
function Listener() {
handler.value = {};
defineProperty(this, "_handler", handler);
}
function fire(callback) {
callback.call(this.target, this);
}
var
proto = Listener.prototype
defineProperty = Object.defineProperty,
handler = {
value: proto
},
empty = []
;
Object.defineProperties(
Listener.prototype,
{
addEvent: {
value: function addEvent(type, callback) {
var stack = this._handler[type] || (this._handler[type] = []);
stack.indexOf(callback) < 0 && stack.push(callback);
}
},
removeEvent: {
value: function removeEvent(type, callback) {
var
stack = this._handler[type] || empty,
i = stack.indexOf(callback)
;
-1 < i && stack.splice(i, 1);
}
},
fireEvent: {
value: function fireEvent(e) {
typeof e == "string" && (e = {type: e});
e.target = this;
(this._handler[e.type] || empty).forEach(fire, e);
}
}
}
);
return Listener;
}());

Sunday, December 26, 2010

100% Client Side Image Resizing

... I know, I have said "Happy Holidays" already, but yesterday, after a (annoying) picture upload in Facebook, I had a an idea ... why on earth I should have a Java plugin to perform images resizes on Facebook? Why on earth if I don't have such plugin I have to wait the possibly extremely long upload, up to 10x slower for high quality images, stressing Facebook servers for such "simple" operation as an image resize/resample could be?

The FileReader Interface

In the W3C File API, I guess part of the HTML5 buzzword, we can find all we need to perform the operation we want totally on client side. The interface is called FileReader, and it provides functionalities to read chosen files from an input node with type file, and that's it: we can even disconnect from the network and keep resizing and saving images without problems.

The Canvas Trick

Still into HTML5 buzzword world, the canvas element and it's 2dContext.drawImage method is the key to perform a resample/resize operation. It's not about changing a DOM Image node size and show it, it's about creating a totally fresh new image with exactly desired pixels size.
Once this is done, it is possible to send via Ajax the bas64 encoded image or it is possible to simply save the created image or reuse it, or resize it again ...

The Demo Page

This is the demo page I gonna show you soon, the code is hopefully self explanatory:

<!doctype html>
<html>
<head>
<title>JavaScript Image Resample :: WebReflection</title>
</head>
<body>
<input id="width" type="text" value="320" />
<input id="height" type="text" />
<input id="file" type="file" />
<br /><span id="message"></span><br />
<div id="img"></div>
</body>
<script src="resample.js"></script>
<script>
(function (global, $width, $height, $file, $message, $img) {

// (C) WebReflection Mit Style License

// simple FileReader detection
if (!global.FileReader)
// no way to do what we are trying to do ...
return $message.innerHTML = "FileReader API not supported"
;

// async callback, received the
// base 64 encoded resampled image
function resampled(data) {
$message.innerHTML = "done";
($img.lastChild || $img.appendChild(new Image)
).src = data;
}

// async callback, fired when the image
// file has been loaded
function load(e) {
$message.innerHTML = "resampling ...";
// see resample.js
Resample(
this.result,
this._width || null,
this._height || null,
resampled
);

}

// async callback, fired if the operation
// is aborted ( for whatever reason )
function abort(e) {
$message.innerHTML = "operation aborted";
}

// async callback, fired
// if an error occur (i.e. security)
function error(e) {
$message.innerHTML = "Error: " + (this.result || e);
}

// listener for the input@file onchange
$file.addEventListener("change", function change() {
var
// retrieve the width in pixel
width = parseInt($width.value, 10),
// retrieve the height in pixels
height = parseInt($height.value, 10),
// temporary variable, different purposes
file
;
// no width and height specified
// or both are NaN
if (!width && !height) {
// reset the input simply swapping it
$file.parentNode.replaceChild(
file = $file.cloneNode(false),
$file
);
// remove the listener to avoid leaks, if any
$file.removeEventListener("change", change, false);
// reassign the $file DOM pointer
// with the new input text and
// add the change listener
($file = file).addEventListener("change", change, false);
// notify user there was something wrong
$message.innerHTML = "please specify width or height";
} else if(
// there is a files property
// and this has a length greater than 0
($file.files || []).length &&
// the first file in this list
// has an image type, hopefully
// compatible with canvas and drawImage
// not strictly filtered in this example
/^image\//.test((file = $file.files[0]).type)
) {
// reading action notification
$message.innerHTML = "reading ...";
// create a new object
file = new FileReader;
// assign directly events
// as example, Chrome does not
// inherit EventTarget yet
// so addEventListener won't
// work as expected
file.onload = load;
file.onabort = abort;
file.onerror = error;
// cheap and easy place to store
// desired width and/or height
file._width = width;
file._height = height;
// time to read as base 64 encoded
// data te selected image
file.readAsDataURL($file.files[0]);
// it will notify onload when finished
// An onprogress listener could be added
// as well, not in this demo tho (I am lazy)
} else if (file) {
// if file variable has been created
// during precedent checks, there is a file
// but the type is not the expected one
// wrong file type notification
$message.innerHTML = "please chose an image";
} else {
// no file selected ... or no files at all
// there is really nothing to do here ...
$message.innerHTML = "nothing to do";
}
}, false);
}(
// the global object
this,
// all required fields ...
document.getElementById("width"),
document.getElementById("height"),
document.getElementById("file"),
document.getElementById("message"),
document.getElementById("img")
));
</script>
</html>


The resample.js File



var Resample = (function (canvas) {

// (C) WebReflection Mit Style License

// Resample function, accepts an image
// as url, base64 string, or Image/HTMLImgElement
// optional width or height, and a callback
// to invoke on operation complete
function Resample(img, width, height, onresample) {
var
// check the image type
load = typeof img == "string",
// Image pointer
i = load || img
;
// if string, a new Image is needed
if (load) {
i = new Image;
// with propers callbacks
i.onload = onload;
i.onerror = onerror;
}
// easy/cheap way to store info
i._onresample = onresample;
i._width = width;
i._height = height;
// if string, we trust the onload event
// otherwise we call onload directly
// with the image as callback context
load ? (i.src = img) : onload.call(img);
}

// just in case something goes wrong
function onerror() {
throw ("not found: " + this.src);
}

// called when the Image is ready
function onload() {
var
// minifier friendly
img = this,
// the desired width, if any
width = img._width,
// the desired height, if any
height = img._height,
// the callback
onresample = img._onresample
;
// if width and height are both specified
// the resample uses these pixels
// if width is specified but not the height
// the resample respects proportions
// accordingly with orginal size
// same is if there is a height, but no width
width == null && (width = round(img.width * height / img.height));
height == null && (height = round(img.height * width / img.width));
// remove (hopefully) stored info
delete img._onresample;
delete img._width;
delete img._height;
// when we reassign a canvas size
// this clears automatically
// the size should be exactly the same
// of the final image
// so that toDataURL ctx method
// will return the whole canvas as png
// without empty spaces or lines
canvas.width = width;
canvas.height = height;
// drawImage has different overloads
// in this case we need the following one ...
context.drawImage(
// original image
img,
// starting x point
0,
// starting y point
0,
// image width
img.width,
// image height
img.height,
// destination x point
0,
// destination y point
0,
// destination width
width,
// destination height
height
);
// retrieve the canvas content as
// base4 encoded PNG image
// and pass the result to the callback
onresample(canvas.toDataURL("image/png"));
}

var
// point one, use every time ...
context = canvas.getContext("2d"),
// local scope shortcut
round = Math.round
;

return Resample;

}(
// lucky us we don't even need to append
// and render anything on the screen
// let's keep this DOM node in RAM
// for all resizes we want
this.document.createElement("canvas"))
);


The Resample Demo In Action

First input for the width, second input for the height, if one out of 2 is defined, the resize maintain the aspect ratio.
You can even disconnect your machine from the network, since nothing is absolutely stored or saved in my website, everything simply runs in your machine.
Compatibility? Minefield and latest Chrome work pretty well. I don't have my MacMini with me right now but I will test eventually WebKit nightly later.
Happy end of 2010

Friday, December 24, 2010

Happy Holidays

I'd like to recycle this good old experiment to wish all WR readers nice holidays, if any :D



See you soon next year with new web development adventures ;)

The Status of Mobile Browsing

In this year I have done more tests than ever over all these tiny and shiny portable devices and I'd like to share with the Web community the result of my experiments at the end of this 2010. "why not before xmas, ffs?" ... because whatever you bought as present for you or your relatives, will hopefully be updated soon with latest systems and related browsers :)

The Dedicated WebKit ... Nightmare!

As ppk mentioned already in Front Trends conference, we have basically only 5 browsers in our desktop PCs/Macs/Linuxes machines. Much more fun comes when we think we are dealing with a single browser, a generic WebKit based one, and we discover that there's no browser similar to another one, every bloody device has its own implementation with few exceptions represented by Safari Mobile, almost the same in iPad, iPod, and latest iPhone.

WebKit and CSS(3)

Even if the CSS engine is basically the same for every single specific implementation, the number of supported, and so called, CSS3 features, are platform and device dependent. Something works as expected, something simply does not work, while something pretends to work but it does not until we force the rendering trying to activate Hardware Acceleration.
The classic trick to do this is to apply 3D transformation to the main container of our styled stuff:

#styled-stuff-container {
-webkit-transform: translate3d(0, 0, 0);
}

Above technique could solve many headaches when a portion, or the whole body, looks fucked up ... give it a try but please note that GPU buffer will rarely support big images and these could cause a massive performances impact.
An ideal document size for mobile browsing should not reach more than 2~3000 pixels height ... considering a reasonable width, after that we could have problems.

Tricks a part, the horrible side effect of unsupported CSS features is that features detections are not really a solution ... "eye result" detection would be the way to go but it requires a pixel per pixel check.
The "eye result" detection is something I have invented right now as CSS check automation. We should have a snapshot of the container, saved as png, a snapshot created runtime from the rendered container, impossible with current DOM API, and two canvas elements in order to compare both image data ... where to speed up the process in JS world, we could simply compare the returned base64 encoded result of both snapshots as fast char-by-char (threaded as ints) match (e.g. "a" == "a").
This is fantasy right now, and it implicates complex, bandwidth greedy, operations I would never suggest ... but I am just saying ... that we should never trust the result we have on our desktop WebKit or another device WebKit based, we should always test results in target if we would like to avoid surprises.
Finally, messed up CSS could cause indirectly so many computation behind the scene we cannot even imagine ... until we discover the the whole interaction is compromised.
As example, those pages strongly styled in an unreasonable way through tons of overwritten or inherited CSS, in a deeply nested DOM, simply are unusable!

WebKit and JavaScript(ES5)

Under the flag "we support HTML5", many things implemented in ES5 specs are already there indeed. In few words these tiny devices are already "10 years" ahead whatever destktop browser based on Internet Explorer ... which is good, which gives us the possibility to forget all crap we use to detect, filter, change, assume, until now.
This is the reason 99% of common web libraries out there are obsolete when it comes to the massive amount of features detections these libraries use to understand the exact version of IE, Firefox, or Opera ... all this stuff is crap, is bandwidth unfriendly, and unnecessary.
A good library for mobile browsing is a library dedicated for mobile browsing ... where even features detections could cost time (slower CPUs) and where most of the time these features detection, specially those for edge cases, can be dropped in favour of the good old User Agent string.
Yes, you read correctly, features detections we know could simply fail in all these variants of WebKit based browsers.
Some device could expose hosted features that are not available, some other could not expose anything but still support what we are looking for ... there are many examples that caused me nightmares during my experiments and no simple solution.
The User Agent sniff sometimes is the best, cheap, fast, solution we could possibly adopt and it will rarely fail when it comes to mobile.
Last, but not least, faster WebKit implements V8 engine, the google diamond, but others may implement the classic JavaScriptCore, with or without "Extreme" acceleration.

Native JSON Support

Almost all mobile browsers support native JSON. This is essential for fast and safe JSON strings and JS objects conversion into JSON strings.
I am counting seconds for the day Douglas Crockford JavaScript implementation of JSON will be redundant/superfluous, same as I am counting seconds until attachEvent will disappear from the Earth!

GeoLocation API

A mobile browser that does not come with GeoLocation API support is a death device. Mobile therm talks by itself, it's the user "on the way", full stop. Remove the possibility to share or know the location and good by "to go" experience.

session and local Storage Limits

Whatever freaking cool idea you come with these storages is not enough. What all these demo and examples around the net are saying is not exact. First of all the correct way to set an item is via official API, and not via direct access:

localStorage.setItem("setItem", "whatever");

// rather than
localStorage.setItem = "whatever";

// cause you don't want unexpected results later
localStorage.getItem("setItem"); // whatever

localStorage.setItem // ... what do you expect?
// a method or "whatever"

To know more about this problem, if interested, have a look.

Finally, and most important, setItem could fail once the storage reaches the memory limit which is not exposed (hopefully yet) through the API.
In few words we can have a nice Exception the moment we try to set an item, even the same, and the storage is "full".
To avoid problems, even if this is not a solution, use a bloody try catch block every time we need to set an item:

try {
localStorage.setItem("key", "bigValue");
} catch(e) {
// now we are fucked ... where do we put bigValue?
// we can still do stuff or clear some value
localStorage.clear(...)
}

The limit I am talking about is around 2Mb but it may vary.

Database API

Something nobody liked that much, something I love since the beginning. The SQLite database behind the scene is the best portable, tiny, and cross platform database engine we could possibly use on a browser. I am not a big fun of all these NoSQL fuzz, just use what the fuck you need when the fuck you need.
In this case the Web Database API provides a nice message automatically when the application tries to store more data than allowed, letting us being able to pass the limit specified at the beginning.
A good compromise is to set the initial storage value to 2 megabyte, maximum 5, and after that limit it will be the device able to allocate more space if necessary, adding other 2, up to 5, megabytes to curent database.
Rather than try catch mandatory blocks, we have callbacks for error handling but, right now, I have never been able to reproduce in a real scenario problems with the SQLite database size.

WebWorkers

These beasts could be the ideal solution in a multi-core device. Unfortunately, webworkes do not come for free with current mobile CPUs. It does not matter if these are operated behind the scene since the scene itself could interact slower than usual due tasks priorities.
Not a big deal considering webworker are not widely supported yet ... but still bear in mind the CPU is "that one", you better learn better algo or JS practices to speed up things rather than delegate piece of massive stuff to computate on the background.
A tiny temporary block is, in my opinion, much better than a persistently slow interaction due webworkers.

Touch Support

Touch events are the mandatory choice for mobile web development ... people should completely forget about mouseover and this kind of interaction bullshit, when it comes to device ... there is no fucking mouse on device, and these events should be used only as quirk fallback for those devices that do not expose properly touch events.
Touches are truly simple and everything we need for whatever interaction: touchstart, touchmove, touchend.
There will never be a touchmove without a touchstart, neither a touchend without a touchstart. Things are slightly complicated when we assume that a touchstart, followed by a touchend, won't fire a touchmove in the meanwhile.
When we start touching our smartphone screen the area we cover with our finger may vary due pressure on the screen. If a touchstart event has been fired already but the area is "enlarging" from the same finger, we won't have another touchstart, we will be notified with a touchmove.
There are concepts as "touch tolerance" that are already applied on all layers, included hardware, but this is not enough if we would like to have full control.
Finally, touch events are a classic example where features detections fails. The only way to be sure 100% that the device will work with touch events is to listen to both touchstart and mousedown and accordingly with the one fired first, usually the touch if fired, we can switch/communicate that the device is compatible. All our detections may fail accordingly with the device or the implemented WebKit version.

The Click Event

In some device, as is for example the delicious Palm Pre 2 I am testing these days (thanks again Palm!) there are no touches, even if the browser exposes them, so it is not possible to drag or scroll via JavaScript but it is possible to trust the classic click event.
The click is indeed the only universal fallback we can use to simulate interactions. Both new and old devices, included most recent Windows Mobile with that brEwser, will always react on click events. Pal Pre 2 does not expose right functionality for quirks mousemove neither ... and I am talking about web pages, if we create our own Application through Mojo framework ... well, things changes (again).

The Canvas Element

Almost every mobile browser supports canvas. Unfortunately, the Hardware Accelerated Canvas is still a myth. Canvas will be HW Accelerated hopefully soon, but what I have spotted right now, is that as example iOS 4.0.2 or lower has a tremendously faster canvas manipulation than iOS 4.2, or the latest iOS you can install in your iPad or iPhone. I am really sorry if you have already screwed up your mobile browsing experience updating this OS with latest ... since we all know you cannot go back now, let's hope Apple QA will test properly, next update, canvas performances ... epic fail from my point of view (and I can easily demonstrate it with eye test over exactly same operations ...)

Flash ... maybe

The world #1 plugin sucks for mobile ... not all of them, but still sucks. At least the render is faster via bytecode than canvas one could be, but since we have HTML5 video element as well and since the interaction in a small screen cannot contain all those details and cool effects that Flash has given us 'till now, I don't think Flash should be considered mandatory for a mobile experience ... still, if present, Flash could be our best friend as fallback for all those "not implemented yet" HTML5 features (or in some case, give us even more ... accordingly with security risks we may face).

Gestures ... if any ...

I still don't know how to pronounce this word properly ... but it does not matter.
The only browser able to expose properly gesture and to make developers life easy is Safari Mobile. Even if all recent smartphones support gestures on OS level, this topic seems to be the most complicated thing ever to expose through the browser.
The problem number one is the conflict that these events could cause with System Gestures. If I think about Palm Pre 2 "cards" interaction and the way I love to use this phone, I can instantly imagine how many side effects "my own gestures" could cause from UX perspective ... specially if I am able to avoid System gestures defaults. The problem number two is that we may find gestures variants, just to make our life, as developers, more interesting ... isn't it? Well, as soon as these variant will be part of the newer browser version we can find on these devices, I will dedicate a post about them ... so, patience is the key! (isn't it Weronika :P)
However, if touches events are exposed correctly, some crazy dude out there (and I am not excluding me) could implement gestures through touches events.
gesturestart is when touch list length is greater than 1, gesturechange is only if gesturestart has been fired and both scale and rotate are simple Math operations, while gestureend is fired when the touch list length goes down to 1 or 0 ... almost easy stuff, we don't really need them as long as touches work.

Opera Mobile

This is a must have browser if you want a common cross device web experience or a better browser than the one you have preinstalled in that phone.
Opera Mobile does not expose touches or gestures and the interaction is compromised but as render engine and web surfing, it is a pretty damn fast and cool browser that will be hopefully installable in the most recent Windows Mobile OS, since this has the worst browser you could ever imagine, compared with all others.

Mozilla Fennec

This is in my opinion too young and too featureless to compete with WebKit based implementations first and Opera Mobile after. Mozilla guys are working harder and improving a lot ... but still too much to do and hopefully a stable and cool release before next summer?

Nothing Else

Starting from the fact I could not test all of them, and ppk is here again the man you are looking for, all I can say is that the only superior mobile browser is WebKit based, no matters which branch, as long as things I have talked about are, more or less, supported.

Marry Christmas Everybody

Monday, November 01, 2010

UX vs IP Based Language

I start being sick of this epic fail and many famous website do this ... I am Italian, I am living in Germany, but my OS as every software or device I have is in English ( and I don't know German yet ) !

The Problem

If you live in your country and you have software in your own language, you probably never spotted what I am talking about. Actually, what you have probably appreciated instead, is the fact if you write in your url bar www.google.com you'll find directly the one translated and relative to your country ... how cool is it?
My tiny winy problem is that if I write the same right now, I am redirected to google.de .... most likely in German with all settings in German as well, even the confirm button, no matter if I managed somehow to reach that point and changed the language ...

How Difficult Is It

Every single fucking browser sends an Accept-Language header with 99.9% of the time the current browser language or, in the worst case scenario, the Operating System one.
If it's not about the server, we have the same behavior on the client via navigator.language ...
In both cases I am sending a bloody en-us string that cannot surely be confused with de-de one, isn't it? But it does not matter, in 2010 and its growing globalization, these "clever" websites still rely on IP address to define the spoken language, but how wrong is this?

Language IS Context Dependent

Let's imagine we are simply traveling ... OK? Good, We have hot spots services in the airport or we are having a coffee in some local chain with wireless connection ... OK? Now we try to visit websites we use to check from home, from our country, and never with a single problem, cookies or not .... we are in the cloud, the one we would like to use everywhere but being behind some other IP address, the cloud does not recognize us anymore ... still cool, uh?
In few words, if we are simply surfing the web there is no reason in this world to trust the current provider for our spoken language.

Location And Laws Context

There are mainly and only two reasons our IP address should be considered, a map application unable to use the W3C Geolocation API, so we are more into a fallback situation, or country laws for all those services that may works differently accordingly with current country (e.g. YouTube)

Everything Else Is UX

If the website we use on daily basis does not recognize us instantly we may feel that something went terribly wrong, isn't it? And how many could freak out the moment even few links around a search field are in a completely extraneous language?
Moreover, if I decided to use English software, rather than italian, it means I made a choice and surely I cannot really complain if websites are always in English even if I am in italy or Germany ... it's the other way round: I expect this, and I am instantly confused the moment this does not happen.

The Failing Google Chrome Attempt

The ridiculous part of this story is an evident UX conflicts inside Google teams, the search engine and the translation one.

In my case, if I start Google Chrome and I go to google.com I am:
  1. redirected into google.de, it does not matter if I explicitly typed .com
  2. the whole search engine in in German
  3. a top bar lazily informs me that the page is in German, would you like to translate?
Oh ... Really??? So the browser understands I am based on English but the server of the same company decided I am German ... how cool is it?
The company that more cares of performances is doing a redirect, a lazy navigator.language analysis, in order to help me with the wrong choice made by the server ... and guess what? The translation team is not brilliant, is everything else that looks dumb!
It must be said that at least I have a Google in English link easy to spot ... but many other sites don't!

User Agent Myths

A user agent should follow W3C standards and AFAIK all do, more or less. It is not about the browser, the platform, it is simply about the only thing that I do believe is consistent across every platform: the language. Of course it's easy to hack a userAgent in order to show a different language ... but who the hell gonna do it for daily browsing? Even the IP could be hacked via userAgent, the one that sends it, isn't it? So why on earth people adopted such silly strategy to define the user language?

The Internet Cafe Context

If we are still thinking about edge cases ... believe me, these are truly rare. Even an internet cafe, most of the time populated by foreigners, could simply create accounts and most used languages set for each account. As example, we could have the user English, the user Deutche, the user Italiano, etc etc ... and the moment we login with this user the OS, and hopefully the software, will be presented in the same language. At that point, every website that will present content based on IP language could be easily labeled as dumb, because in this world were everybody travels and therms as mobile are used on daily basis by marketing, companies behind the same marketing do not get it: it's NOT about the IP!

Monday, October 25, 2010

JavaScript Coercion Demystified

This post is another complementary one for my front-trends slides, about performances and security behind sth == null rather than classic sth === null || sth === undefined.
I have already discussed about this in my JSLint: The Bad Part post but I have never gone deeper into this argument.

Falsy Values

In JavaScript, and not only JavaScript, we have so called falsy values. These are respectively: 0, null, undefined, false, "", NaN. Please note the empty string is empty, 'cause differently from php as example, "0" will be considered truish, and this is why we need to explicitly enforce a number cast, specially if we are dealing with input text value.
In many other languages we may consider falsy values even objects such arrays or lists:

<?php
if (array())
echo 'never'
;
?>

#python
if []:
print 'never'


Above example will not work in JavaScript, since Array is still an instanceof Object.
Another language that has falsy values is the lower C, where 0 as example could be considered false inside an if statement.
Falsy values are important to understand, specially if we would like to understand coercion.

About Coercion

In JavaScript world, coercion is considered a sort of evil and unexpected implicit cast, while in my opinion it's simply a feature, if we understand it and we know how to use it.
Coercion is possible only via == (eqeq) operator, but the thing is that everything is properly implemented cross browsers accordingly with ECMAScript 3 Standard.
This is the scary list newcomers have probably never read, directly from the even newer ECMAScript 5 specification, just to inform you that coercion will hopefully always be there, and nothing is evil.

The comparison x == y, where x and y are values, produces true or false. Such a comparison is performed as
follows:


  1. If Type(x) is the same as Type(y), then

    1. If Type(x) is Undefined, return true: undefined == undefined

    2. If Type(x) is Null, return true: null == null

    3. If Type(x) is Number, then

      1. If x is NaN, return false: NaN != NaN

      2. If y is NaN, return false: NaN != NaN

      3. If x is the same Number value as y, return true: 2 == 2

      4. If x is +0 and y is −0, return true: 0 == 0

      5. If x is −0 and y is +0, return true: 0 == 0

      6. Return false: 2 != 1


    4. If Type(x) is String, then return true if x and y are exactly the same sequence of characters (same length and same characters in corresponding positions). Otherwise, return false: "a" == "a" but "a" != "b" and "a" != "aa"

    5. If Type(x) is Boolean, return true if x and y are both true or both false. Otherwise, return false: true == true and false == false but true != false and false != true

    6. Return true if x and y refer to the same object. Otherwise, return false: var o = {}; o == o but o != {} and {} != {} and [] != [] ... etc etc, all objects are eqeq only if it's the same


  2. If x is null and y is undefined, return true: null == undefined

  3. If x is undefined and y is null, return true: undefined == null

  4. If Type(x) is Number and Type(y) is String, return the result of the comparison x == ToNumber(y): 2 == "2"

  5. If Type(x) is String and Type(y) is Number, return the result of the comparison ToNumber(x) == y: "2" == 2

  6. If Type(x) is Boolean, return the result of the comparison ToNumber(x) == y: false == 0 and true == 1 but true != 2

  7. If Type(y) is Boolean, return the result of the comparison x == ToNumber(y)

  8. If Type(x) is either String or Number and Type(y) is Object, return the result of the comparison x == ToPrimitive(y): ToPrimitive means implicit valueOf call or toString if toString is defined and valueOf is not


About last point, this is the object coercion we are all scared about ...

var one = {
valueOf: function () {
return 1;
},
toString: function () {
return "2";
}
};

alert(one == 1); // true
alert(one == "2"); // false

If we remove the valueOf method, we will implicitly call the toString one so that one == "2" or, more generally, {} == "[object Object]".

null == undefined And null == null, Nothing Else!

99% of the time we do a check such:

function something(arg) {
if (arg === undefined) {
}
}

We are asking the current engine to check if the undefined variable has been redefined in the current scope, up to the global one, passing through all outer scopes.
Even worse, we may end up with the most silly check ever:

function something(arg) {
if (arg === undefined || arg === null) {
}
}

which shows entirely how much we don't know JavaScript, being the exact equivalent of:

function something(arg) {
if (arg == null) {
}
}

with these nice to have differences:

  • null cannot be redefined, being NOT a variable

  • null does NOT require scope resolution, neither lookup up to the global scope

The only side effect we may have when we check against null via == is that we consider for that particular case null and undefined different values .... now think how many times you do this ... and ask yourself why ...

Performances

Once again I send you to this simple benchmark page, where if you click over null VS undefined or null VS eqeq, or one of the lines showed under the header, you can realize that while it's usually faster and safer, it provides even more control when compared against the ! not operator.
The only way to reach better performances when we mean to compare against an undefined value in a safer way is to declare the variable locally without assigning any value, so that minifiers can shrink the variable name while the check will be safer.

// whatever nested scope ...
for (var undefined, i = 0; i < 10; ++i) {
a[i] === undefined && (a[i] = "not anymore");
}


There Is NO WTF In JavaScript Coercion!

Coercion in JavaScript is well described and perfectly respected cross browser being something extremely simple to implement in whatever engine. Rules are there and if we know what kind of data we are dealing with, we can always decide to be even safer and faster.
Of course if we are not aware the strict equivalent operator === is absolutely the way to go, but for example, how many times you have written something like this?

if (typeof variable === "string") ...

being typeof an operator we cannot overwrite neither change, and being sure that typeof always returns a string there is no reason at all to use the strict eqeqeq operator since String === String behavior is exactly the same of String == String by specs.
Moreover, as said before, coercion could be absolutely meant in some case, check what we can do with other languages, as example:

# Python 3
class WTF:
def __eq__(self, value):
return value == None

# Python 2
class WTF():
def __eq__(self, value):
return value == None

# in both cases ...
if WTF() == None:
"""WTF!!!"""

While this is a C# example:

using System;

namespace wtf {

class MainClass {

public static void Main (string[] args) {
WTF self = new WTF();
Console.WriteLine (
self ?
"true" : "false"
);
}
}

class WTF {
static public implicit operator bool(WTF self) {
return false;
}
}

}

Can we consider some sort of coercion latest cases as well? It's simply operator overloading, virtually the same JavaScript engines implemented behind the scene in order to consider specifications points when an eqeq is encountered.
Have fun with coercion ;-)

Sunday, October 24, 2010

The Layer ... Of The Layer ... Of The Layer ...

When I read tweets like this one I cannot avoid a quick comment but the reason I am posting, is simply to explain that every time we write a web page/application, we are dealing with at least 4 different layers.
Moreover, this post is complementary for few slides I have introduced at front-trends, specially regarding the "avoid classic OOP emulation when not necessary" point.

Layer #1: JavaScript Libraries

We all know the DOM is a mess, and this is most likely the reason we chose a JS library rather than deal directly with possible problems we can have when we develop an x?HTML page.
Even if many developers don't care, I keep saying that every millisecond gained in this first layer, the page itself, is important.
Moreover, if we have a good understanding of the JavaScript programming language, we can easily realize that all these "Java Pretending Style Frameworks" emulating classic inheritance and OOP are not easier to maintain neither faster for what we need on mobile devices, included Netbooks.
The "easier to maintain" fuzz, associated with "Java style JavaScript", a sentence that does not make sense itself, is only a Java developer point of view.
Well written JavaScript without any "wannabe another language" pragmas, is truly much easier to both understand and write, modify, or fix, while the great magic behind this or that framework/library could become our first enemy when something goes wrong and we would like to understand and debug that magic 'cause we had a problem and we have strict deadline that may not match with a bug lifecycle.
Finally, as easily demonstrated via this test page, we can all spot how much more it costs to simply initialize a new instanceof constructor, compared with proper way to go natively via JavaScript, in that case made easier by this essential script, developed following TDD and tested here cross browser.
Anyway, common sense first and fast production quality, should always be kept in mind when we decide an approach, rather than another one. So, here frameworks play usually quite good role, the one to bring same functionality cross browser.
But what is a browser?

Layer #2: The Browser

As libraries are considered an abstract way to reach same goal in all browsers, browsers are simply abstract applications able to bring the web cross platform.
This is were the browser speed may vary, accordingly with the platform, and were every technique able to speed up render ( DOM+CSS engine such Gecko, Trident, others ) and JavaScript ( engine a part such V8, JavaScriptCore, SpiderMonkey ) is more than welcome. These guys are implementing any sort of trick to make the page and the code that fast, even if they have to deal with different operating systems. And guess what is an operating system?

Layer #3: The Operating System

We are even lucky if the browser deals directly with the operating system graphic API, since many other middle layers could be part of this stack ( flash or third parts plugins, as example ).
You cannot expect that Linux, Mac, and Windows, just mentioning fews Desktop related ( more choices on mobile world ) magically display and provide browser functionalities via the same API. We would need something like a jOSQuery library here to make it happens ... but even worse, every operating system may have another abstract layer able to use, as example, Hardware Acceleration.

Layer #4: The Hardware

Open GL ES 2.0 is simply another abstraction able to transform API calls into specific hardware driver calls which means that starting back from the DOM and the used WebGL or CSS3 with HW support, things have been modified, translated, re-created at least a couple of times.
In few words, if we asked too many things to do on first abstract layer, and being the first the slower one, nothing can be that fast.

As Summary

We, as web or scripting programming languages developers, rarely think that performances on the highest level ever can be that important but unfortunately, that highest level is the slowest one ever so, specially if we would like to reach best frame rate via canvas, WebGL, or CSS3 animations, it's highly recommended to be sure that the strategy/code we are using is the best one for our requirements.
As example, if we spend just a millisecond more to create each object we need for a single frame, we can easily switch from 30fps, a decent visual framerate, to 29 or less, were things will start to be visually slower for our eyes ...
Finally, kudos for Opera Mini and its growing market share, I am pretty sure it will become soon the IE for mobile platforms, making developers life easier, being a portable browser fallback for whatever website or application, hoping will not have all IE problems we all know.

Thursday, October 21, 2010

Front Trends 2010 - My Talk

My talk is finished, there were probably too stuff to talk about and it was hard to make a clear point, but I am willing to better explain myself posting here about main points.

Slides without me trying to show stuff online do not probably make much sense but these are here: ft2010 WebReflection Slides

The benchmark I have showed that should run in any browser ( at least those A grade ) is here. During this talk I have tried to explain what each test means. You can grab the benchMark function from the source, it's simple but it ruffling did the job.

The showed "problematic parent" example is here.

Tests for my essential Class are here.

Talk Summary


I have tried to explain that sometimes we should take care of performances techniques, accordingly with the goal and the target.
I have showed how things could go slow in whatever Netbook, regardless hardware acceleration.
What I have not been probably able to explain , is that it's up to our common sense decide when we should avoid common good practices or not, and I won't link here the IE9+iPhone/iPad canvas experiment since I would like to talk with openstreetmap.org guys before and eventually create a proper GitHub project for their slickviewer, mobile version.

Thanks everzbody for listening, all the best.

Sunday, October 17, 2010

Pre Authorization Meta Tag Proposal

Under the HTML5 flag, browsers are bringing to our desktops or devices exciting features such GeoLocation, File, and many others such camera, microphone, system access, etc ...

The Problem

While this is good from possibilities point of view, the activation approach historically sucks. Flash and it's video or microphone activation shows a dialog that asks the user to authorize media access while browsers are lazily asking via JavaScript the same. The real life scenario we all know is definitively different when a page is using a screen reader, and this article and video about twitter UX should be enough to open our eyes: something is wrong.

Solutions

If we ever used an Android device, or we have download applications from whatever mobile store, we should be familiar with the installation warnings and confirmations we suppose to read and accept in order to grant application access to anything it needs to work properly.
This simply means that once we accept we won't be bothered anymore and the application can easily work as expected.
It's all about privileges and in my opinion it would be nice to have similar approach in our browsers as well, also to make web application even closer to native one.


Proposal

Following the "don't break the WEB" approach, all we could do is put a meta tag, as we do for viewports, specifying all those Technologies/API we would like to use in our webpage. This is an example:

<meta name="grant" content="GeoLocation,Camera" />
<meta name="grant" content="System" />

The proposal should ask at the very beginning and only once if the webpage could access these functionalities and the user can decide before what should be available and what should not.
The "before" action is important 'cause in this Ajax era it's extremely easy to loose focus runtime with whatever activation request and this is so wrong.
The list of granted API should be reachable via userAgent via specific method such:

navigator.hasGranted("GeoLocation")

or similar, so that eventually we can decide via JavaScript if we would like to ask again runtime, as we do now, or simply provide an alternative solution or message, maybe showing an "ask again to activate" button, remembering to put back the focus in the right context.

Alternative

Web developers could implement similar concept asking with the very first script access to one or more API and put the page focus back. With GeoLocation, as example, the user will chose immediately his preferences without having surprises in the middle of a session, or later.

// As Soon As Possible
var HAS_GEO_LOCATION = false;
try {
navigator.geolocation.getCurrentPosition(function (result) {
// so that other scripts could check if already available
HAS_GEO_LOCATION = true;
// notify the event in any case
var evt = document.createEvent("Event");
evt.initEvent("geolocationready", 1, 1);
evt.data = result;
// implicit window context
dispatchEvent(evt);
});
} catch(e) {}

A usage example could be something like:

// script loaded after a while ...

if (HAS_GEO_LOCATION) {
doFreakingCoolStuffWithGeo();
} else {
addEventListener(
"geolocationready",
doFreakingCoolStuffWithGeo,
false
);
}


We can eventually specify the handleError callback as well but actually this is part of the HAS_GEO_LOCATION value, if there is an error no reason to insist, simply assume that there is no geo location and go with the fallback, if any.

What do you think?

Friday, October 15, 2010

Technical Reviews: Bestsellers!

Just a quick one about two technical reviews out of two I have recently done for @stoyanstefanov and @cjno for these completely different books: JavaScript Patterns and Test-Driven JavaScript Development.

Right now these are both Top 10 Bestsellers and trust me: other JavaScript Jedis have been involved, you won't regret these lectures! ;-)



Tuesday, October 05, 2010

JavaScriptCore via Terminal

Just a quick one, maybe only for a new Mac comer as I am, I found truly annoying I have already Python, Ruby, and even PHP everywhere available in my command line but not JavaScript?

What The Fuck

Even Windows runs .js files natively and since ages, I wonder why on earth after I have downlaoded the whole XCode SDK "my JavaScript" was not there available for all my needs.

OK, OK, node.js is already on /bin, linked and working properly, but now I have the system default JavaScript Engine that comes automatically with WebKit or the "IE for Mac" aka Safari.

How to link jsc to bin folder

A title that produces zero outcome on Google, could be hopefully better addressed via this blog, and this is how I have solved:

sudo ln -F /System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Resources/jsc /usr/bin

The Current folde ris the link to the latest one, all those threads about the ..../A/... folder are not automatically updated if A becomes B, as example.
So, now I can type jsc wherever I am and use JavaScript power whenever I want, writing just quit() anytime I need.
I hope this helps, it took a while for me to sort it out.

Saturday, October 02, 2010

Apple UX Fails with Mac Mini

Update
Following Daniel suggestion (first comment), I have grabbed a cabled keyboard and a cabled mouse from a colleague and I have been able to finish the initial procedure. Happy to be a Mac Mini user now, it works like a charm!


as tweeted already, apparently there's no way I can buy a dishwasher. Last time I almost came back home with a pretty cool Samsung Blue Ray Player ... but I bought nothing, this time I did a mistake: I bought a Mac Mini.
The time my new Mac Mini has been switched on is no longer than 10 minutes, and right now I am still unable to use it ... and I would like to tell you the story ...

Nothing On The Package

It's clean and small, no requirements or dependencies specified anywhere. Being the package obviously close, I have not been able to RTFM.
The only thing I took care of was the absence of the HDMI cable ... not a big deal, I have bought one and this, at least, works like a charm!

Pretty Cool And Useless Gadgets

Wireless keyboard and wireless trackpad, these gadgets are a must have for my room configuration: a 32" LED Sony Bravia screen with Full HD capability and a comfortable (and cheap) sofa about 1 meter far away from the screen. The plan was perfect, the result still a disaster.

Totally Stuck On First Run



As you can see from this picture, there is nothing I can do. Trust me, both keyboard and trackpad are switched on, and the lovely King of Operating Systems is unable to recognize them and, for this reason, unable to let me use the consistent amount of money I have spent few minutes before.

Epic Fail

All Apple gadgets and products come ready and easy to use, this is a key for this company and the reason I gave up trying to avoid its products ... these are simply great.
I could never expect such problem using all official Apple/Mac stuff, and if this is a known issue either a marketing strategy (I should buy a mouse now, uh? I won't!) it's a massive hole in the whole UX excellence we think when we talk about Apple.
Please put massive cubic labels over each Mac Mini saying: without our mouse, you can't do anything!

wru against wru: version 1 ready

This shot has been token on 13th September 1923, when W.H. Murphy demonstrated the efficiency of his bulletproof vest, the one that sold later to NY Police Department.

Above image has been historically used for different topics and the current one is "how much we trust what we sell".

Do You Trust Your UT Framework?

I wasn't kidding that much when I wrote about "test the testing framework" in my precedent wru post. The overall Unit Test Frameworks code coverage is poor, specially those with all the magic behind the scene, magic that does not come for free.

Use The Framework Itself To Test The Framework

This is a common technique that may result in a reliability deadlock. If we trust our UT Framework and we use it to test itself, the moment we have a problem with the framework we'll never know ... or even worst, it will be too late.

Don't Trust "Magic" Too Much

If the framework is simple and it does not pollute each test with any sort of crap, we can surely use it to test the framework itself without problems while if this framework elaborates and transforms our tests, it may become impossible to test it via the framework itself due scope and possibly context conflicts for each executed test.
This may produce a lot of false positives for something in place theoretically to make our code more robust.

The wru KISS approach

With or without async.js, wru does few things and now it's proved that it does these things properly. I don't want to spend any extra time for a library that I should trust 100% and if I know that all things this library should do are working as expected, I can simply "forget to maintain it" (improve, eventually) and use it feeling safer.

99.9% Of Code And Cases Coverage

Loaded on top of whatever test, wru uses few native calls and the assumption is that these are already working as expected (accordingly with ES3 or ES5 specs).
The new wru test against wru covers all possible tests combination, where setup and teardown could fail on wru itself or for each test, and assert should simply work in a test life-cycle. This means we could assert inside setups and teardowns as well, simply because these calls are fundamental for a single test and, if present, must be part of the test result. A problem in a setup could compromise the whole test while a problem in a teardown could compromise other tests. Being sure that nothing went wrong is up to us but, at least, we can do it via wru.

Can you do the same with your UT Framework? Do you have the same coverage? Have fun with wru ;)

Tuesday, September 28, 2010

Opera, Inevitably Unexpected

Update


Opera fellas works at speed light, the problem described in this post has been patched already, great stuff and thanks!



Just a quick one, about what I have discovered with Opera 10.62 when I have tested wru against this browser ...

// host object
var xhr = new XMLHttpRequest;

// this is true
alert("addEventListener" in xhr);

// this is undefined
// not even null
// simply undefined!!!
alert(xhr.addEventListener);


The Problem

99% of libraries out there are assuming that key in object is one of the fastest and most reliable way to have features detection.
Today, we know that this assumption is wrong.
It's not about the reproducibility of the problem:

var o = {};
o.key = o.key;
"key" in o && o.key;

It's about an ...

Epic Fail (Already Fixed!)

The engine "behind the scene" is broken. Whatever it happens there, we have a broken chain through pseudo inheritance that exposes publicly a method that does not exist, which brings us down the assumption that host objects are not tested before the release ... or surely not their "apparently valid" methods.
Nothing else to say, come on guys, you've always been pioneer and good fellas, so please don't release these mistakes, thanks.

Monday, September 27, 2010

WRU: My New Tiny Unit Test Library

The last and only developer able to let me fully appreciate the beauty of Test-Driven JavaScript Development has been @cjno, but regular "fights" with @mrgnrdrck and @sleistner have always helped me as well ;)

This post is about my tiny wru library and general thoughts about JavaScript Unit Test Frameworks.

WRU: Essentials Asynchronous Tests

The wru library is a copy and paste matter, and it is possible to test it directly here.

Why Wru

Well, sometimes I write truly small projects during my free time, and a setup that takes "zero seconds" with still a visual result of my tests could be all I need. Also for my personal projects I rarely need a massive logic behind the UT framework ... simple things are often better, but I will explain why afterwards.

Look, if you refresh, it changes!

What I have learned from Christian while I was editing his book code is that order should not matter. In my opinion there are cases where order could matter, specially when a test may depend over the setup of another one. The discussion may be long and tedious, but basically while all frameworks I know follow a for or for/in order, based on current engine implementation since for/in order has never been granted by specs, wru may have random order, and it's easy to flag it as true.

Look, it uses setTimeout and XMLHttpRequest for tests and it works!

Pretty much, wru does not give a shit about asynchronous calls but if we implement the extra file, called async.js, wru will always wait that async variable will be false before it continues.
It is true that other test could be "coolly" executed in the meanwhile, but at the end of the day the result comes when all of them have been executed ... so ... why bother? Just wait, and wru will go on by itself.

Public or Privileged Setup and Teardown

A fresh new setup per test may be worth it, that's why wru checks for these properties in the current test first, and wru itself after. If there, these are called with a temporary object shared for the test lifetime where we could store whatever we need since it's just passed by reference, as every other JS object. Handy, hu?

Compatibility?

You can try your smart phone or whatever desktop browser in this list: IE7+ ... all others. wru should simply work.

Essential Is The Key

Christian smart framework a part, 90% of Unit Test frameworks I have seen are based on following bullshit:

  • with statement, the statement everybody is scared about is far away from our production code but unbelievably trusted for all major unit test frameworks I have seen ... no comments at all ... I am simply waiting ES5 and strict tests that will nicely fuck up all your effort to write tests so far with frameworks based on the with statement

  • function destructuration, another monster able to destroy the meaning of scope and everything else that starts with the name safe environment. If your framework parses functions and methods in order to understand them, throw it away

  • any sort of magic, where magic may be good for production code and exposed API, but rarely the way to go for unit tests

  • polluted environments, via with, native prototypes and whatsoever in order to speed up those few minutes we use to write a test ... the one we suppose to trust ...

  • assertWhatever, where "Whatever" is part of the magic assertion I will never get ... and I tell you why ...



The Number One UT Framework? The Console

console.assert is probably the only thing we truly need for whatever test we would like to run in an almost clean environment, where FireBug, as example, is able to screw up a basic selector like document.getElementsByTagName("div") polluting the DOM with it's console node (a freaky and custom <firebug> node element was too clever, isn't it?)
Unfortunately, console.assert may not be available in some environment and we prefer a visual green response, isn't it? Well, with wru we can use our own style for results so that we could make the testing page as cool as possible.

Decide What To Assert

The only thing wru would assert is a truish value, and we are the only one able to make the result true ... this sounds too boring, isn't it?
The classic assertTrue is in my opinion the most ambiguous thing ever in a dynamic typed language.
All objects are true, an eqeq rather than eqeqeq could be true as well and I would like to know which one the framework is considering true.

// false by specs
console.log(
{} == true
);

// true by specs
console.log(
{valueOf:function(){return true}} == true
);

In few words, are we really sure that assertion was the one I meant? Or we have to investigate and "test the testing framework" to remember what happens behind scene?
With wru, we write the assert and if it fails, it fails. Now, tell me that you trust more the magic behind your framework ...

Stubs And Mocks Gotchas

While a stub is usually tied to a function signature, a mock is usually tied to a whole object, or environment, behavior.
What we test in this case is what we expect ... and this is ... too easy, isn't it?
We are not considering that stubbing a behavior we may have on real world so many side effects we cannot even imagine.
First of all, we are not sure that our arguments are valid 'cause we don't care about "the scene behind" our test ... and this may be good, as far as we are sure that our code works perfectly without knowing that an argument or the expected result produced by those arguments created an anomaly in the environment, and maybe an expected one.
Stubs and Mocks have been one of the "major fights" I have done with Christian during the editing, and as I have said he has been able to enlightening me about the topic ... yeah, now I got it, but stubs and mocks are still something I don't want to deal with my little projects, while surely I need them on daily basis real world tests scenarios.
For these reason, the KISS approach, I have decided to leave stubs and mocks for serious cases/applications/frameworks, but you won't find them inside wru ... but of course, we can all implement our stubs and mocks using a wru.assert(...) when it necessary during that specific test.

The Ruby World

I have heard many times Ruby community is really focused on Unit Test. Unfortunately JavaScript is not Ruby, and most of the frameworks I have seen have been created by Ruby guys that most likely did not get entirely the difference, and the beauty, of JavaScript. Please don't fall in the "common" Java developers hole, where everything should be based on new Class, you can do better!

Conclusion

I am already using wru for simple local projects and I am quite happy with its simplicity and I hope somebody will be able to "grab the concept" and create an even better framework for JS community since right now ... things are not that perfect at all.
Christian Johansen library is probably following the same simplicity, bringing much more "in the house". I suggest you to have a look but even said that, I do believe the road for a complete and standard JSUT Framework, obviously compatible with both server and client, is still unfortunately long ... well, wru is my little attempt, but yeah, I have to mock the wru DOM node in a server side environment ... but will come soon ;)

@jsconfeu after parties epilogue

too bad I wasn't planning to be in Berlin this week end for this conference, and too cool I have been able at least to meet such crowd of JS pirates after the conference!

This post is about what I have found in JSConf.eu "after events", and I do believe it should be shared.

Great To Meet You All

Heroes, colleagues, "just developers", it does not really matter! Everybody I have talked with was in the "friendly, shary, skilled, interested" mood, pretty cool for this JS community that is clearly growing up on daily basis in Europe as well ... Yeah, you simply have to accept that JavaScript is everywhere, client, server, whatsoever, and nobody will stop us!
You can still think it's a toy language, not a real programming one (scripting is part of the therm tho) and bla bla bla ... this community of real pirates will always be there to answer your questions and show how freaking cool is this programming language!

Twitter Is The One!

If you are following speakers and other participants as I have done, you would have felt somehow in the conference. Of course I have missed everything there, and twitter could not give me same feeling, but it's impressive how much devs share realtime and how easy is to virtually follow presentations via posted slides, comments, and all sort of links.

Party Time!

Good organization on both Friday*, Saturday, and Sunday, with almost every speaker there for the "after conference". Places, as well as number of JS folks, were really cool: an unexpected atmosphere for what somebody may simply define a "geek meeting": music, games, and inevitably #beers, great stuff!
*next Friday dinner please in a proper Schnitzel and Kartoffeln place!!!

Special Thanks

These are developers I have met the first time outside the Web and I would like to thank ... and if you don't follow them ... you better should!

  • @andrewdupont, the Prototype and script.aculo.us party man

  • @dalmaer ... uh wait, we met different times before :D

  • @jdalton, the "all you can dream about JS libraries" pirate

  • @paul_irish, the real HTML5 evangelist

  • @phiggins, a "crazy dude" you'll never recognize without his hat

  • @rmurphey, the one that "would never hire me and my WebReflection arrogance" :P

  • @robertnyman, the "JS and HTML5 buddy" you have to meet in person

  • @stoyanstefanov, the "kick ass" client/server performances man

  • @thomasfuchs and @amyhoy, the Scripty and "learn JS properly!" folks


Apologies if I forgot somebody but ... you know, I had few beers as well ;)

Thanks again everybody and see you soon!

Sunday, September 26, 2010

Promote JS!

From JSConf.eu a nice initiative to better promote JSINJ thanks to MDC documentation.

JavaScript JS Documentation: JS Array indexOf, JavaScript Array indexOf, JS Array .indexOf, JavaScript Array .indexOf

I would like to share my thoughts about the initiative:

  • it's time for developers to understand that if they know a library (e.g. jQuery) it does not mean they know JavaScript. Too often I have talked with "JS Developers" unable to add a simple DOM listener in a W3/IE way. This initiative may eventually bring to all JS folks the beauty and simplicity of the language, which is not only inside this or that framework

  • MDC has always been a reference to me but it must be said it does not include everything and sometimes it has Gecko specific pages that may disorient us if our target is cross browser

  • MDC may contains errors as well and many examples are not optimized at all but for some reason took as "the only way to do that". In this case Array extras, as example, are not always the most logic or performances oriented

  • as I have done different time there, it is possible to edit the content adding hopefully valid contribution



Have fun Pirates!

Monday, September 20, 2010

Fragment and Vertex Shaders: My Way To Load

I have finally received the fifth and amazing version of the OpenGL SuperBible book and I have already started digging into it, really well done for what I can tell.

The book is mainly focused on "real OpenGL development", something surely more suitable for tough C/C++ developers rather than Web Monkeys like me but since the book includes an OpenGL ES 2.0 related part, and since latter spec is basically what we can find in WebGL, it's always better start learning what's next knowing history and background of the used technology ... and here I am :-)

Something Already Wrong

I am not completely sure about "who started this techniques", John Resig with his micro template inside script nodes with a type text/html may be the indirect responsible for a sort of growing "monster" we can see in almost every WebGL related example ...

HTML Embedded Shaders, the Web 3.0 NO-GO

Let me pass the therm, but 3D websites are not that far away from reality. Minefield, Chrome, WebKit, and probably others, are working hard with Khronos and WebGL and I do believe official support will come later this year with next browsers releases ( ... hoping IE9 final won't "block the world" avoiding WebGL support ... )
Back in the topic, the common examples technique is a step backward in 1999 where runtime loading did not exists (aka: Ajax or scripts injection) and an HTML page was a trash bin for any kind of rubbish.

A Better Technique

We are in 2010 and we want use latest technologies, so why should we use old and deprecated one? Let me show this simple getShader function alternative:

// our shaders base path
loadShaders.base = "shader/";

// our shaders loader
function loadShaders(gl, shaders, callback) {
// (C) WebReflection - Mit Style License
function onreadystatechange() {
var
xhr = this,
i = xhr.i
;
if (xhr.readyState == 4) {
shaders[i] = gl.createShader(
shaders[i].slice(0, 2) == "fs" ?
gl.FRAGMENT_SHADER :
gl.VERTEX_SHADER
);
gl.shaderSource(shaders[i], xhr.responseText);
gl.compileShader(shaders[i]);
if (!gl.getShaderParameter(shaders[i], gl.COMPILE_STATUS))
throw gl.getShaderInfoLog(shaders[i])
;
!--length && typeof callback == "function" && callback(shaders);
}
}
for (var
shaders = [].concat(shaders),
asynchronous = !!callback,
i = shaders.length,
length = i,
xhr;
i--;
) {
(xhr = new XMLHttpRequest).i = i;
xhr.open("get", loadShaders.base + shaders[i] + ".c", asynchronous);
if (asynchronous) {
xhr.onreadystatechange = onreadystatechange;
}
xhr.send(null);
onreadystatechange.call(xhr);
}
return shaders;
}

With above minifier friendly function we can avoid shaders on the page. The natural advantage is that we can properly organize shaders in a structure like this one:

root

shader

vs // vertex shaders

ShaderName.c

fs // fragment shaders

FragmentName.c

Having a proper extension means that we can edit these files with highlighted syntax and we can edit these files a part, without looking for id or scripts inside an HTML page. Fragment and Vertex Shaders are our "application templates", so why on earth should we include them in the layout? Via loadShaders we can use cached shaders, share shaders, etc etc, and here some usage example.


vra gl = canvas.getContext("experimental-webgl");

// synchronous order, one shader
var myFragmentShader = loadShaders(gl, "fs/myFragment");

// synch, more shaders
var shaders = loadShaders(gl, [
"vs/what",
"vs/ever"
]);
// [whatShader, everShader]


// asynchronous loading
loadShaders(gl, ["fs/what", "vs/ever"], function (shaders) {
var
fragmentWhatShader = shaders[0],
vertexEverShader = shaders[1];
;
});


// asynch in "don't care mode, just cache them"
loadShaders(gl, ["fs/what", "vs/ever"], true);



Features


  • Synchronous or Asynchronous loading

  • Multiple Loads (unordered compilation for each result)

  • Ordered Results, (order respected accordingly with paths)

If I have forgotten something please point it out but even more please, whatever you like or not this solution, do not include shaders in your HTML page (OK, OK, gotcha, for some example it may make life easier but ... you know how people get examples ... right?)

Cheers :)

Wednesday, September 15, 2010

The Rebecca Murphey's Challenge

What is the best/easiest way to understand if a {{ProgrammingLanguage}} developer is a {{ProgrammingLanguage}} dev and not simply a CV bloater?

A Technical Test

Nothing simpler than this, and this is what @rmurphey has recently done with a nice JavaScript challenge published on GitHub.
Unfortunately in some country (Italy as example) IT is still a matter of piece of paper for whatever {{ProgrammingLanguage}}, even those completely unrelated with the generic developer academic course/program, as often happens with JavaScript, the most used one and probably the less considered one at the same time ( ... hopefully it comes after VB ... )
Anyway, Rebecca comes from North Carolina and we all know in USA "they know something about IT", don't we? :)

Developers Rumors

I have probably arrived too late, but apparently lots of developers more updated than me knew about this test ... and this is good.
When developers are happy to be tested they demonstrate already to be brave, convinced about their knowledge, and ready for new challenges and I am pretty sure Rebecca will thank them all.
About me? I am just "challenges addicted" so even if I am not interested in Rebecca proposal, I could not avoid this test and this post aim is to describe question after question, pretending I would have applied ... are we ready? :)

Considerations

JavaScript is extremely flexible and expressive so there is rarely a universal solution for a single problem. Moreover, I did not know Rebecca and I have read nothing about this test when I have tried to consider that some answer may be redundant while I have re-thought some other to provide a better answer. Finally, to solve the test it's strictly necessary to make a lot of assumptions since questions are often too poor. Let's start now!


1: how could you rewrite the following to make it shorter?



if (foo) {
bar.doSomething(el);
} else {
bar.doSomethingElse(el);
}

Assumption #1: doSomething and doSomethingElse are truly named like that and this is the answer thinking in a non abstract way:

bar["doSomething"+(foo?"":"Else")](el);

Assumption #2: the method name is just indicative:

bar[foo?"doSomething":"doSomethingElse"](el);

Latest approach could be optimized if the same operation should be repeated after and using two strings references for method names so that minifiers can play well.

2: what is the faulty logic in the following code?



var foo = 'hello';

(function() {
var foo = foo || 'world';
console.log(foo);
})();

Do you remember my good old/shorter way to address the "undefined" string to a local variable?

var u = typeof u;

The logic is the same, but Rebecca does not know me so I think I should explain that once we declare local scope variables these have prevalence against the outer scope and a function scope is always invoked resolving in advance function declarations and knowing already declared scope variables.

(function () {

alert([onFnCall, notAfter]);

// tons of JavaScript and ...

for (var onFnCall = 1; 0;);
function notAfter(){}

alert([onFnCall, notAfter]);

}());

The first alert will be undefined, function notAfter(){} while the second one will show the onFnCall assigned value as well.
What is important to know is that no error occurs on the first alert and it will always be undefined, even if there is an outer scope variable with the same name.
I have an old IE related post about this, have fun :)

3: given the following code, demonstrate you know JS objects



var Thinger = function() {
return this;
};

Thinger.prototype = {
bar : 'baz'
};

var foo = new Thinger(),
bim = new Thinger();

The first thought after the very first line of code has been something like: Dude, you don't like the non (IE) standard but unbelievably helpful "name" property, don't ya? Neither you like saved bytes

function Thinger() {
return this;
}

The instant second thought on the instant second line has been something like: "... neither you present good example! Why on earth that bloody redundant and pointless return this which is worldwide recognized as implicit?"

function Thinger() {}

So now, accordingly with the rest of the code, I can at least go on reading it ...

3.1: how would you override the value of the bar property for the variable foo without affecting the value of the bar property for the variable bim?



foo.bar = foo.bar; // it's enough

The moment we assign a property to a generic instanceof Object is the moment we are sure that obj.hasOwnProperty("directly assigned") will return true, even if the assignment is for an undefined value.
Fair enough, the moment I execute latest line of code, is the moment I ask foo to access its prototype chain and assign the returned value, if any, to the property with the same name. Is bim affected by this operation? Not at all!

3.2: how would you affect the value of the bar property for both foo and bim?


Assumption #1: we are talking about the initial case, without operations in the middle (e.g. the foo.bar = foo.bar; I have written already)

Thinger.prototype.bar = "via chained properties";

Any JS developer knows that objects properties access look up for the chained prototype, where if this has no property but still a __proto__, the lookup will continue until we reach the null __proto__:

Object.prototype.__proto__ == null;

In this case life is easy, there is only one chain and the lookup stops immediatly.

Assumption #2: objects creation and the moment we would like to be sure both objects "bar" properties are changed could be performed after any sort of code, included the one posted at the beginning.
With latest assumption we have two options, the most obvious one:

// sub assumption, NO ES5 and defineProperty
foo.bar = bim.bar = "overwrite";

While the second one, still considering no ES5 in place where Object.defineProperty could avoid such operation, is the safer equivalent of the first one:

delete foo.bar;
delete bim.bar;
Thinger.prototype.bar = "via chained properties";

Latter approach could be used to change shared runtime properties or methods in those constructors that would like to track each instance, e.g.

var CrazyStuff = (function () {

// the constructor
function CrazyStuff() {
// with a register
_instances.push(this);
}

// the public magic method
CrazyStuff.defineInstancesProperty = function (name, value) {
_instances.forEach(deleteProperty, name);
this.prototype[name] = value;
};

// some chained property ...
CrazyStuff.prototype.bar = "buz";

// some prototype method ...
CrazyStuff.prototype.destroy = function () {
var i = _instances.indexOf(this);
if (-1 < i) {
_instances.splice(i, 1);
}
};

// the public magic method helper
function deleteProperty(instance) {
delete instance[this];
}

// instances container
var _instances = [];

// ensure indexOf method (quick version)
_instances.indexOf = _instances.indexOf || function (value) {
for (var i = this.length; i--; ) {
if (this[i] === value) break;
}
return i;
};

// same with forEach (quick version)
_instances.forEach = _instances.forEach || function (fn, context) {
for (var i = this.length; i--; ) fn.call(context, this[i]);
};

return CrazyStuff;

}());

var
foo = new CrazyStuff,
bim = new CrazyStuff
;

alert(foo.bar); // buz

foo.bar = "overwritten";
alert(foo.bar); // overwritten

CrazyStuff.defineInstancesProperty("bar", function () {
alert("YO, even methods!");
});

foo.bar(); // YO, even methods!

As I have said before and as you can see, it's never that easy to answer a generic JS question without thinking or creating different ways to obtain similar results.

3.3: how would you add a method to foo and bim to console.log the value of each object's bar property?

Surely avoiding runtime changes to the prototype, even if I have just showed some CrazyStuff.
I am not sure if the question is appositely wrongly formulated, but the only answer I could provide locally was changing the initial example:

Thinger.prototype = {
bar : 'baz',
logBar: function () {
console.log(this.bar);
}
};

It does not matter if Rebecca meant something else, I have already demonstrated how easy is to change runtime properties (and then methods) and I would never use the same technique for a simple method.
The Assumption, in any case, is that there is a public object called console and that this has a log method, otherwise the first instanceOfThinger.logBar() call will produce an Error.

3.4: how would you tell if the object's bar property had been overridden for the particular object?


At least in three ways, considering that ...
Assumption #1: no fools man, too easy

instanceOfThinger.hasOwnProperty("bar");

If you don't know hasOwnProperty method, I am pretty sure you have failed the whole test and you are not into JavaScript at all (yet). It is still probably worth it to keep reading this post to hopefully learn something new :)

The Assumption #2 is that we are talking about generic objects. In this case we cannot be sure that hasOwnProperty method is inherited from the Object.prototype (e.g. host objects) so, as safer solution, I would do something like:

Object.prototype.hasOwnProperty.call(object, "bar");


The last Assumption #3 is that I am a wannabe, but I am not a surrender, since in the Ninja code there is no space for loosers:

// optimistic, still ignorant, attempt
function hasOwnProperty(obj, name) {
var result = false, value;
if (name in obj) {
value = obj[name];
delete obj[name];
result = !(name in obj && obj[name] === value);
if (result) {
obj[name] = value;
}
}
return result;
}

hasOwnProperty(foo, "bar");

Latest attempt will easily fail if both instance and the generic prototypeOf have a property with the same value.

4: given the following code, destroy recursively



var myObjects = {
thinger : new myApp.Thinger(),
gizmo : new myApp.Gizmo(),
widget : new myApp.Widget()
};

Once again, to many assumptions to consider here. It's not specified if the environment is clean, or sandboxed, as it's not specified if myObjects life cycle ends up after the operation. To be sure about almost everything, here the code:

function destroyThemAll(obj) {

for(var key in obj) {
// the "PrototypeJS in da house" way
// if (myObjects.hasOwnProperty(key))
// slower and completely pointless
// for a "destroy" operation
// all we want is to call destroy
// if present
obj[key].destroy && obj[key].destroy();

// alternative:
// paranoid way, ensuring nobody
// attached a destroy property that
// is not a function
typeof obj[key].destroy == "function" &&
obj[key].destroy();

// the optional leaks paranoic way
delete obj[key];
}

}

destroyThemAll(myObjects);

I am sure you got the fact I hate when problems lack of description details :)

5: given the following array, loop over it and do stuff



var myArray = [ 'foo', 'bar', 'baz' ];

This question has basically no answer since it's not specified what we would like to reach. Is it performances? is it readability, is it both? The only point clear is:
you can assume the library of your choice is available
Oh really? Dear Rebecca, I would seriously avoid to hire any developers that is not able to solve this problem without a library ... seriously!!!
In any case, I don't even need to comment this question since Morgan Roderick already created a test page where almost all possible solutions are in place, included my performances oriented in revision 25.
Despite those examples, one of my first attempt was to use the classic trick to repeat strings, instantly screwed up by that space in the middle.

// fast string repeat
function str_repeat(str, times) {
return new Array(++times).join(str);
}

str_repeat("a", 3); // aaa


6: how could you improve the following code?



$(document).ready(function() {
$('.foo #bar').css('color', 'red');
$('.foo #bar').css('border', '1px solid blue');
$('.foo #bar').text('new text!');
$('.foo #bar').click(function() {
$(this).attr('title', 'new title');
$(this).width('100px');
});

$('.foo #bar').click();
});

Here we are again, while I am sure somebody wrote the $.each loop for the precedent question, in this one it's not even mentioned that the library is jQuery ... so why should I think in a jQuery optimization way?
Even if my name is for some reason inside jQuery source code, my first thought, without knowing Rebecca and the fact she is into "jQuery world", has been something like: "dude, the dollar function has been showed via PrototypeJS before jQuery and has been used or re-invented from every developer, me included ... the chainability may be optional, you know that, don't ya ..."
So, this was Assumption #1: dollar does not mean jQuery and chainability.

// non jQuery way
$(document).ready(function() {
// cache the result once
var $el = $('.foo #bar');
// no chainability
// no knowledge of
// methods signature
// the example worked?
// this should work as well
$el.css('color', 'red');
$el.css('border', '1px solid blue');
$el.text('new text!');
$el.click(function() {
// $el refers to 1 element
$el.attr('title', 'new title');
$el.width('100px');
});
$el.click();
});

Then of course Assumption #2 has been jQuery oriented

// assuming jQuery
$(document).ready(function() {
var $el = $('.foo #bar')
.css({
color: "red",
border: "1px solid shit"
})
.text("new text")
.click(function () {
$el
.attr('title', 'new title')
.width('100px')
;
})
.click()
;
});

There is a sub assumption in latter case, the $el acts only to the first element of the CSS query, if not the $(this) inside click() is still necessary.
Now, you know what? Since Rebecca forgot to specify that jQuery was the library, I did not bother myself to check the API ... sorry if it's wrong, but the question is to me incomplete.

7: what issues do you see with the following code? how would you fix it?



(function() {
var foo;

dojo.xhrGet({
url : 'foo.php',
load : function(resp) {
foo = resp.foo;
}
});

if (foo) {
// run this important code
}
})();

Let's assume I am a framework user and I know that dojo is a framework with a xhrGet method ... the problem may be that the call is Asynchronous.
I say "may be" 'cause I am sure somebody could have changed the default behavior for whatever reason so ... Rebecca, are you looking for framework users or JavaScripters?
Anyway ...

(function() {
var foo;

dojo.xhrGet({
url : 'foo.php',
load : function(resp) {
// assuming foo is reused
// no need to assign otherwise
if (foo = resp.foo) {
// run important code
}
}
});

})();


8: how could you rewrite the following code to make it shorter?



(function(d, $){
$('li.foo a').attr('title', 'i am foo');
$('li.bar a').attr('title', 'i am bar');
$('li.baz a').attr('title', 'i am baz');
$('li.bop a').attr('title', 'i am bop');
})(dojo, dojo.query);

Shorter? Here I am:

// new lines for blog readability
["foo","bar","baz","bop"].forEach(function(c){
dojo.query("li."+c+" a").attr("title","i am "+c)
});

But since I have assumed that I could have used any library, even if 90% of the time all we need is just a bit deeper knowledge of JS to obtain the same faster result, it must be written instantly after the IE version:

for(var a=["foo","bar","baz","bop"],i=a.length;i--;)
dojo.query("li."+a[i]+" a").attr("title","i am "+a[i])
;

Shortest ever, isn't it? But maybe Rebecca would have liked to know that dojo argument was completely redundant, considering that dojo.query does not use this internally as dojo reference, otherwise the whole thing would not have runned at all?

9: how would you improve the following code?



for (i = 0; i <= 100; i++) {
$('#thinger').append('

i am thinger ' + i + '

');
$('#gizmo').append('

i am gizmo ' + i + '

');
}

I really would like another Morgan like page for this test, assuming we are still talking about performances.
The number one thing to do is to avoid DOM manipulation inside loops, whatever library we are using. So, for sure, append should be moved after the loop, then we can talk about performances.

var
i = 0,
re = /\{name\}/g, // ES5 friendly
str = new Array(102).join(
'

i am {name} {i}

'
).replace(/\{i\}/g, function () {
return i++;
})
;
$('#thinger').append(str.replace(re, "thinger"));
$('#gizmo').append(str.replace(re, "gizmo"));

In my attempt I don't even use a loop at all but append() a part, I really would like to compare different ways to create those 2 similar strings ... maybe I should create one ...

10: a user enters their desired tip into a text box; the baseTotal, tax, and fee values are provided by the application. Find issues ...



function calculateTotal(baseTotal, tip, tax, fee) {
return baseTotal + tip + tax + fee;
}

This question has been the most ridiculous one I have found in this test since it is a complete nonsense.
First of all, the number of assumptions are unlimited, nothing is clear and ... the design is crap!
Seriously, why on bloody earth I would create a function that accepts 3 variables from an abstract "application" that I suppose I should trust (should i?) and the only argument provided anyhow from the user is ... the second one?
calculateTotal(fromApp1, fromUser, fromApp2, fromApp3) ... I don't really know what you think, but this is one of the crappiest signature I have ever seen ... so Rebecca, please don't be mad at me, but can I rewrite the whole thingy?

10++: a user enters their desired tip into a text box that is gonna be summed with the rest of spent money. Write a function able to return the sum of the user tip, provided via input.value, and a generic number, this time provided by the application.


Now we talk ...
Since I do believe this task is about security, I am quite sure few developers provided this kind of solution for the tip parsing:

function getTotal(tip, amount) {
// cast float compatible
// without function calls
tip *= 1;
if (
// isNaN is not reliable
// what we know by specs
// is that NaN != NaN ... so
tip != tip ||
// if tip is negative
// the user is trying
// to fuck the bill!
tip < 0
) {
// in both cases
// we don't want to go on ..
throw "invalid tip";
// muda-h-acker !!!
}
return amount + tip;
}

If it comes to JavaScript and user exposed runtime changeable code, the word security is a sort of joke.
Security must be on server side, but it is surely true we can help the latter one improving client side security as much as possible.
So, why I have created that function?

// makes every number negative
var parseFloat = (function (parseFloat) {
return function (f) {
f = parseFloat(f);
return f < 0 ? f : -f;
};
}(parseFloat));

// makes every integer negative
var parseInt = (function (parseInt) {
return function (i, base) {
i = parseInt(i, base);
return i < 0 ? i : -i;
};
}(parseInt));

// negative abs
Math.abs = (function (abs) {
return function (n) {
return -abs(n);
};
}(Math.abs));

// always false
var isNaN = function () {
return false;
};

I could go on forever so ... we don't want to trust anymore online forms, do we?
Even worse, if we put the secure logic inside a closure, we could always find the user with an older Firefox version able to reach the private scope and change things there ... scary, uh? Now try to make my attempt fail, since not a single call is changeable (expect the function itself via older Firefox and the scope, private or not).
Repeat with me: security is never enough and on client side it's almost absent :P

11: given the following data structure, do stuff with properties



var menuItems = [
{
id : 1,
name : 'Salad',
extras : [
'Chicken', 'Steak', 'Shrimp'
]
},

{
id : 2,
name : 'Potato',
extras : [
'Bacon', 'Sour Cream', 'Shrimp'
]
},

{
id : 3,
name : 'Sandwich',
extras : [
'Turkey', 'Bacon'
]
},

{
id : 4,
name : 'Bread'
}
];

We can assume any library we like ... and that's why I have chosen JavaScript, you gotta love it :D

var result = menuItems.map(function (item) {
return item.name + (item.extras ? " (" + item.extras.join(", ") + ")" : "");
});

Too easy task at number 11, I feel like I have missed something here ... benchmarks Morgan? :)

BONUS 1: write code such that the following alerts "Hello World"



say('Hello')('World');

... am I missing something here?

// solution one
// the easy one
var say = function (hello) {
return function (world) {
alert(hello + " " + world);
};
};

// solution two
// the less memory one
var say = function (content) {
if (say.content) {
alert(say.content + " " + content);
content = "";
}
say.content = content;
return say;
};


BONUS 2: what is the faulty logic in the following code? how would you fix it?



var date = new Date(),
day = date.getDate(),
month = date.getMonth(),
dates = [];

for (var i = 0; i <= 5; i++) {
dates.push(month + '/' + (day + i));
}

console.log('The next five days are ', dates.join(', '));

At my first try I did a mistake ... I stopped reading inside the for loop!
If like me you have database and server side experience, including Ajax/ActionScript calendars manipulation, you know which one is the first problem ever with dates: we cannot sum days or months that easily.
That's it, whatever this task asks, the first date I have thought, being the day incremented, has been the new year, aka: 31st December.

In few words, every end of the month above loop will populate the dates array with values like:

...
12/32
12/33
12/34
...

Does that Date make any sense? No it does not, no reason to investigate more ... the logic is already crap.
Let's fix it:

// incomplete!
for (var i = 0; i <= 5; i++) {
date.setDate(day + i);
if (month != date.getMonth()) {
day = -i;
month = date.getMonth();
}
dates.push(month + '/' + (day + i));
}

However, another thing we should always remember is that months and days, unless properly formatted, are almost always from 0 to 11, for months, and 0 to 30 for day of the month.
This means that while the day can be increased, the month should be showed properly adding the classic plus one.
This is the first part of the problem, and I am pretty sure the reason this challenge has been placed online at the beginning of the month is not a coincidence, nice trap Rebecca ;)

If we keep reading we can spot something else we could consider as faulty logic:
The next five days are
OK, so we have a loop that goes from 0 to 5 included, which means 6 values: 0,1,2,3,4,5
We can already spot there is something wrong here, so we either fix the string writing "next six days" ... or we simply fix the loop.
However, we should be carefully, because if we talk about next days, the current one should NOT be included.
This is the proper solution for this last task:

var date = new Date,
day = date.getDate(),
month = date.getMonth(),
dates = [];

// next 5 days
for (var i = 1; i < 6; i++) {
// set the next day
date.setDate(day + i);
// verify that the month did not change
if (month != date.getMonth()) {
// if it did, set day as -i
// removing from "i" the loop start: 1
day = -(i - 1);
// re assign the month
month = date.getMonth();
}
// month + 1 AND day + i
dates.push((month + 1) + '/' + (day + i));
}

console.log('The next five days are ', dates.join(', '));


Conclusion

The description of a problem/task is fundamental, no discussions about it. We all know sometimes our customers don't even know what they want ... it's true, but if we do not insist asking details, anything could become a massive mess. A single detail could make the difference, the real goal is even more important ... in this case we had to guess a lot, make assumptions, spend more time than necessary to be sure our "customer", in this case Rebecca, would have been satisfied.
It does not matter if Rebecca will ever consider us, the thing that matters is that we learn to take things carefully and we remember that 2 similar solutions, logically speaking, could have completely different performances impact in a more complex/structured application.
We should chose carefully, analyzing implications, browser features, security model, and whatever is necessary to do our task as good as possible and our goal will be already closer.

I hope you have appreciated this post, maybe learned something or, even better, corrected me where I have done wrong, and also suggestions are welcome :)

Last, but not least, I do hope Rebecca will spend some time to read this post and "judge me" properly but AFAIK she gonna write about this test tomorrow so stay tuned in her blog.



Update
That was fast and ... I did not pass the test!
Alex S wrote the reason, anticipating Rebecca thoughts, fair enough :)