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

Friday, September 25, 2009

Chrome Frame Always On IE Toolbar Button

As promised in the CF ML, here I am with the first Chrome Frame Button application.



It's beta not because of its functionality, it works 100% at least in my old laptop, but because when you click the button the Chrome Frame is always on or of as expected, but to see the new icon or the new label we need to restart IE.

Anyway, this button is not created to switch every second, this button is "just for fun", as fun was the first always on application.

How it works? Grab the zip file from my chromefix project. Unpack it, and read the file README.TXT ... it's really simple, basically a double click and nothing else

Thursday, September 24, 2009

Software Quality - We Are Loosing It

This may sounds silly, surely not technical, but today I've lived the last drop before crackpots!

IE6 Inside The Cash Point

I am not joking, I have no idea how many cash points use windows and IE to run a 7 screens software. Have you never noticed a "click clack" while you are performing your operations?
OK, maybe banks do not even buy Microsoft licenses, or maybe those are dedicated cache machine version of Windows, but I could never imagine to find a windows popup with an error in a cache machine, it is ridiculous!
Those one with just text? Well, they look old and ugly, but I've rarely seen one disabled.
We have dozen of valid Operating System able to perform the same software for years without requiring a single reboot. How difficult will be to create an OS specific for a cash point where operations are always the same, adding just 1 image format supported? What I mean is that you can find active screens with lottery ads inside running 24/7 without problems over a hilarious hardware.
Take one of them, add 20 buttons function, that's all we need to click: £10 and digit few numbers, isn't it?

The Hub 2.0 Router Firmware Disaster

I am having constant problems with my ADSL since the first day. First of all the company wrote in the website that for first 10 days I could have noticed disservice but after everything would have been fine. So far, so cool, I was freaking out thinking "OMG, my router is alive, it programs itself!!!" ... then I have simply realized that this company is just selling, so once they bring you the router they have a ready excuse if things are not working as expected ... you have already signed, and good luck with assistance 5 days a day, without specific hours, and during the week ... sure, I day off to wait somebody for somethig I am already paying.
Moreover, without touching anything, and monitoring the router directly via its interface, they asked me via phone if I was in Wireless or Cable ... I mean: WHAT? THE ROUTER IS TELLING ME ITS SPEED, I HAVE NOT A NETWORK PROBLEM!!!
It does not matter, I am struggling with 160kbps of bandwidth and apparently, even if for 2 weeks everything was almost fine, now it's my problem ... they need to come here ... to do what?
Checking online the firmware of this router has the worst history ever.
Is it that difficult to develop a firmware or this company just payed the cheapest one "who cares about the software if it works somehow"?
Right, now I have the latest version of one of the most problematic firmware I have ever seen. I was complaining with ASUS and its firmware nightmare where nightmare meant 1 every year and now I have discovered than a much simple device has so many software problem ... OK, cheap router, but they sell it like gold, and crappy software ... that's cool!!! I wonder how many problems there could be in a standard configuration as whatever phone line is. Is too noisy? Cable problems? No, it's the router, but they'll never tell us their router has problem. Most likely they'll let us buy a new PC to discover that the problem was not the PC ... cool!

Supermarket Big Chains With Bugged Self Check Out

Again, I am not joking, in the place where I go almost every day to buy something for lunch I hve never seen all self check out machines active without problems, never!
The hardware is pretty simple though, touch screen with basically 3 big buttons, a barcode reader, and a money counter for the change. Simple, isn't it? It's not, 'cause these machines never work more than 2 consecutive days ... always problems. Well done Big Chain, as summary you paid the cheapest machines, and your are paying 10 times more due to constant problems these machines have. Everybody does its business, right? Today there were 2 3 of us stuck in front of these machines all without notes change ... I mean, the machine counts money, it is never wrong with the change, and it does not understand when it is finished? The money scanner knows there's no money left there, and it tries again, and again, and again ... used software did not think that when it's finished, it's finished, the machine should simply start to flash the top red light with a clear warning: I HAVE NO MORE MONEY
This would make everything more efficient, since I spent 10 minutes in a self check out machine rather than 1 in the human driven one ... cool!


Run To Deliver

Too many competitors, but apparently it's not the same about developers quality. This is true for the web, for microwaves, for every electric stuff ... the hardware does not cost anymore, what we pay is always the software. 20 years ago there was less software but hell if it was working as expected. Nowadays, software development time is too frenetic, there is no time to do a proper analysis, no time to properly structure the code, no time to write decent comments, no time to describes problems, no time for brainstorming, no time to find the best solution, the first that quickly work is fine ... everything is a quick fix, and if it is not and we had time to things properly, we won't have time to create unit tests. Agile, SCRUM, Extreme, these therms are rarely concretely applied over whatever development team but they are fashionable therms, so everybody is Agile today ... We used that OS lib, without showing credits anywhere in our sold application, we have quickly fixed everything without testing, but we have respected the ridiculous deadline 'cause the customer is waiting ... but isn't the customer the one unhappy when things do not work as expected?

AS Summary

We need to slow down, we need to think more, we need to understand why that program worked better, why that library is solving this or that problem and how it is doing it, if we would like to be able to extend it or to customize it. This "1 hour deadline" for everything is visible, touchable, on daily basis with daily software wherever it is ... what is going on? We can't blame always outsourcing though, isn't it?

Chrome Frame On By Default ?

A quick one for those interested into Frame switch on.
Two options
  • use regedit to add or modify the key HKCU\Software\Google\ChromeFrame\OptInUrls with char *
  • download my Chrome Frame Switch executable application.

Latter one, is a zip with two versions of the same application, one for 32bit, one for 64bit. The application allows us to automatically set or remove that register key.

Wednesday, September 23, 2009

Google Chrome Frame - A First Look

In one single day the news about Google Chrome Frame has reached, I suppose, every web related company or developer. As posted before, I hope this plug-in will be adopted soon throwing away every other plug-in "record", thanks to its target: the most used, discussed, slow, and not standard, casa Microsoft default browser, Internet Explorer.
I have spent part of my precedent night sleeping testing this little revolution from Big G. and here there are first suggestions, impressions, results.

The Correct Way To Set Chrome Frame

The Google Getting Started guide is a good lecture, but it is not enough.
The Making Your Pages Work with Google Chrome Frame is incomplete, and I will tell you why.
First of all, we need to understand that Chrome is a Runtime Embedded Browser plug-in, not a tag related one then, as Adobe Flash Player is.
Writing something like:
Just add this tag to the top of the page: That's it!
is confusing and not that detailed info.
A meta tag is normally placed in the header one, top of the page, but as soon as developers read about "that's it" most of them tried to add via JavaScript this meta tag to switch engine: this is wrong.
We cannot mess up IE default Trident engine with a completely different one as WebKit via Chrome Frame is. Different are also variables, if any, globals, if any, render itself, and the best case scenario is that everything will break up!
As summary, runtime browser switch is not truly a good practice, for both main page, or iframes, since the Chrome Frame nature is to change the entire browsed content and since it does not make sense to have such hybrid, non-sense, configuration between JScript and V8, Trident and WebKit.
Accordingly, the best way to activate Chrome Frame is to put in the head tag, top of the page, and before whatever JavaScript action, the meta.

<!DOCTYPE html>
<html>
<head>
<title>Google Chrome Frame</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
... the rest of the page, scripts, css, whatever

That is still not it!

Detecting Google Chrome Frame and Prompting to Install

One more time, we need to thanks Google for all this effort but suggested solution is not ideal! (quick update: Alex Russel agrees, so the page is hpefully gonna change soon).
Chrome Frame is, so far, an Internet Explorer related plug-in which means that the external script will not do anything interesting with every other browser such Firefox, Opera, Safari, or Chrome.
Google truncates web pages (body tag) to make things as fast as possible but it is suggesting us a "slowdown without reasons" practice.
The best way to suggest Chrome Frame is to put that external script in a conditional comment:

<!DOCTYPE html>
<html>
<head>
<title>Google Chrome Frame</title>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<meta http-equiv="X-UA-Compatible" content="chrome=1" />
<!--[if IE]><script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/chrome-frame/1/CFInstall.min.js"></script><![endif]-->
</head>
<body>
</body>
<script type="text/javascript">
document.body.appendChild(
document.createTextNode(navigator.userAgent)
);
</script>
</html>

If for some reason we are worried about how to know if IE supports the plug-in, all we need to do is this:

var cf = (function(i,ua){
return i<ua.indexOf("chromeframe")||i<ua.indexOf("x-clock")
})(-1,navigator.userAgent.toLowerCase());
// cf is true when plug-in is installed


Do We Truly Need To Know?

I think IE support cannot disappear today, I wish it would, but that's not gonna happen. If we develop a cross-browser Web application/site is quite useless to understand if we are using the plug in or not, 'cause if Google Chrome will be supported, special features detections a part, the website will simply looks exactly as it looks in Chrome.
I cannot spot a single valid reason, except the Install Prompt for IE, to include that file but my crystal ball says that Chrome Frame is planning to be installed as plug-in in other browsers as well in a not that far future ... so one day maybe it will make sense to remove that script from conditional comments.

Server Side Chrome Activation ?

Not yet, apparently an header in the server with chrome=1 value is useless. I hope this is a temporary issue 'cause to avoid switch delay once Trident has been already started, the server side header could be the best solution. On the other hand, being Chrome a Trident plug-in, I think Trident needs to start before the plug-in can be activated ... uhm, hell problem!

// this won't have effect so far ...
header('X-UA-Compatible: Chrome=1', true);

Update
To understand if the browser will be render the page via Chrome Frame we can use this snippet as example:

<?php
$userAgent = $_SERVER['HTTP_USER_AGENT'];
if(
strpos($userAgent, 'chromeframe') !== false
) {
// your cool standard layout for Chrome
} else {
// your crappy IE dedicated one
}
?>


My First Impression

Enabling runtime Chrome Frame via url, cf: as url prefix, I have tested Taskspeed and many others benchmarks realizing that if I had used Google Chrome the result would have been exactly the same.
The only difference is the little delay, not that little with extremely old hardware, when the meta tag is interpreted and the switch activated runtime, specially the first time.
Chrome Frame is in any case 100% WebKit and Chrome. IE features, included conditional comments, for both layout or script, attachEvent and friends or CSS expressions, are not supported.
While features such V8 multi tab threading is supported ... again, 100% Chrome.

What's Next ?

I am prety much sure the reason this plug-in is not stable is the native OS integration nature of Internet Exploer.
Talking about IE8 we have Accelerators and other specific stuff that will probably not work with this plug-in, but personally I have never used them.
In the Jurassic IE6 case the Operating System dependency is more than hard, and so far it is the most problematic browser but right now I have never encountered a single problem with this plug-in and to make it stable as soon as possible we all need to install it and test it in every single page. This procedure will help Chromium team to better and faster understand possible troubles, if any, so let's contribute: in the worst case scenario we'll have a better Web experience thanks to Chrome overall stunning performances, standards and HTML5 support.

P.S. the Developer console in IE8 should be activatd before the switch, and not after, otherwise with this version it won't work!

Tuesday, September 22, 2009

Web Terminator Salvation - Google Chrome Frame

Google Chrome Frame Bookmark, if you are surfing for whatever reason in IE, right click in precedent link, add to favorite and save as: FINALLY THE WEB, or simply copy this code and past in the website url you are surfing with IE

// corrected via kangax
javascript:void(location.href='cf:'+location.href));



It's the beginning of a Web Revolution, it's the dream of every Web developer, it's the annihilation of the most slow, problematic, non-standard, engine ever: the whatever version inside Internet Explorer!

It's the "Say Fucking What? Buggy Flash Player Yes For Ages And Chrome Frame No?" era, it's something I've been trying for ages without that direct switch, provided by this plug-in, able to forget Internet Explorer except its frame (weird choice about the name though, Google) ... it's the new stats where IE could increase again it's market share who fuckin' care as long as we can finally develop real web applications, is the no more need to wait that pachyderm libraries development ... is that ...

... uh wait, now we have another IE scenario to test ...

Monday, September 21, 2009

One Function To Trap Them All

This is a quick one. This technique could have some side-effect I am not aware about but I've never seen it so far in any library. Talking about LiveMonitor I have successfully tested same concept to create faster implementation of some of my DOM common code, not yet updated in vice-versa.

document.getElementsByClassName Example


(function(childNodes){

/* Another (C) WebReflection Silly Idea */

// how to re-use them all, just an example
if(!document.getElementsByClassName)
document.getElementsByClassName = function getElementsByClassName(className){
for(var
re = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"),
ret = [], i = 0, l = 0, length = childNodes.length, node;
i < length; ++i
){
if((node = childNodes[i]).nodeType === 1 && re.test(node.className))
ret[l++] = node
;
};
return ret;
}
;

// let the magic happen
})(document.getElementsByTagName("*"));

What we have here?
  1. A trapped live object, probably used in 90% of selector libraries, but performed via scope resolution (the document) and a function execution (the getElementsByTagName method) over all nodes ("*")
  2. a theoretically zero performances impact to retrieve again every node, being live there is no need to refresh it, and being trapped run-time, it will contain few nodes during the first execution
  3. a single scope able to create N functions based on one of the most common created HTMLCollection


What do you think?

CSS Position Fixed Solution

Who does not know CSS 2.1? ... silence (maybe) ...
Good, so who does not know the CSS 2.1 position property? ... silence (still maybe though) ...

Excellent! Finally, who would like to use in a lightweight, cross-browser, unobtrusive way, without JavaScript dependencies, the property fixed? ... silence again, but this time I can spot a different expression in your face ...


Common Browsers With position:fixed Support

  • Chrome
  • Firefox
  • Internet Explorer 7 and 8 but NOT in quirks mode
  • Opera
  • Safari


Common Browsers WithOut position:fixed Support

  • Internet Explorer 6
  • Internet Explorer 7 and 8 in quirks mode
  • WebKit for Android
  • WebKit for iPhone


To Quirks Or Not To Quirks

For backward compatibility reasons IE let developers choose between two box models ... Our loved bloody 64 years* old browser Internet Explorer 6 has never supported such property while both Internet Explorer 7 and 8 do nt support it if we are in quirks mode, a modality tendentiously dead thanks to new simple HTML 5 doctype declaration: <!DOCTYPE html>.
To solve this issue I have created a dedicated file to include via conditional comments which includes a set of "never before that useful" expressions.

Why Expressions

CSS expressions are compatible, so far, only with Microsoft IE browser and they are totally alien for both other browsers and developers. The reason I am saying that is because they are completely unpredictable: it is not possible to easily understand or to predict when expressions will be executed, where, and how!
Technically speaking, being expressions dedicated for CSS hacks, their executions will be performed at least every time the element is somehow involved, and to make it involved, we need to touch some property in order to make expression useful (in this solution case the property offsetHeight of the current node).

The Direct Example

Here we have two pages: the standard or strict mode and the quirks one.
As you can test via your favorite browsers, there are always 5 elements in that page, a top div, a center one, a bottom one, and two divs one left and one right, above and over the center one.

How Does It Work

It is very simple, consider these CSS classes:

/** A WebReflection Solution */
.position-fixed-top {
position:fixed !important;
top: 0;
}
.position-fixed-center {
position:fixed !important;
top: 50%;
}
.position-fixed-bottom {
position:fixed !important;
bottom:0;
}

Hopefully choose name are semantic enough, so it's quite clear that these classes aim is only to position elements, and nothing else, in order to be able to add other classes for whatever other property, zIndex if necessary included.
Choose classes are about most common usage of fixed elements in a page, top, center, or bottom, and adjusting positions or margins it is really simple to put the element in whatever part of the page starting from the bottom, from the top, or the left.
To let the magic be in Internet Explorer 6 and others in quirks mode, these classes are completely replaced, as you can read in IE dedicated file.
Being the IE solution based on CSS expressions, there should not be anything better or quicker than that, render time and call speaking, same should be for memory leaks, timers, and whatever strategy we have adopted 'till now (but of course if there is something better please share!).

Android & iPhone - Not Worth It

These mobile devices implement a stunning browser as dedicated WebKit is, able to render faster than IE8, for example, my last Liquid FX, based on 1 image, and one div, that's it! (congrats IE8 for stretched images rendering time! 7, 6, and 5.5. are much better) ... uh, wait, it's not about IE ...
Android and iPhone have both a great CSS 2.1 support, and even some CSS 3. Unfortunately the position fixed does not work as expected. To fix it I have tried different scripts failing each time. The reason is quite simple: both Android and iPhone block timers or render during scroll, so the effect is that divs move with the scrolled page and only after, eventually, divs come back in the expected position. This is against position fixed idea, and having a truly small screen we should ask our self if it makes sense to cover precious pixels with something fixed there.
It does not matter, as soon as I'll be able to test an iPhone I will continue to optimize my script in order to make the position fixed property usable somehow with mobile devices as well ( center right or center left could be interesting, bottom or top bar quite intrusive for user and/or zooming features ).

How To Implement My Solution

It's simple, if we are in a quirks page, we should include the CSS hacked file after the normal one, and for every IE:

<link rel="stylesheet" type="text/css" href="position-fixed.css" />
<!--[if IE]>
<link rel="stylesheet" type="text/css" href="position-fixed.IE.css" />
<![endif]-->

While for every standard or strict web page we can include the hack only for IE less than version 7:

<link rel="stylesheet" type="text/css" href="position-fixed.css" />
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="position-fixed.IE.css?444" />
<![endif]-->

I can spot a new expression in your face, isn't it?


* if we multiply per 7 dogs age, I think it is reasonable to say that in IT each year could be multiplied for 8

Saturday, September 19, 2009

JavaScript Liquid Image FX

Yesterday I have been in Brixton Academy for Massive Attack concert: amazing!

I have been totally impressed by their choreography: it looked apparently rudimentary stuff but once they started playing I could not avoid to think all the time how beautiful special effects are and how simple, sometimes, they could be for a stunning result.

Liquid FX

I cannot forget my ActionScript Developer past and of my favorite coded special effects has always been the liquid one. What is a liquid effect? Here a preview:


Test Liquid FX Directly In Your Browser

Well, if the preview image is not explicative enough, I am sure this demo page is :)

Update, this Sony VAIO Flash Style Splash Page could be interesting as well, isn't it? And all in 14Kb images, JS, and layout included ;)


How Does Liquid Work

There is a Liquid function, and its configuration object:

Liquid({

// image src, whatever format
src:"myimage.png",

// element to use as Liquid FX container
target: document.getElementById("fx") // $("#fx")[0] for lazy people,

// optional direction, left by default
// accepted: left, right, bottom, top
direction: "left",

// optional scale factor, 2000% by default
// it is how much the image should be stretched
scale: 2000,

// optional speed, 1 to whatever, by default 10
speed: 10,

// optional callback,will be executed at the end of the FX
callback:function(){alert("it's Liquid!")}

// NEW IN V1.3

// optional onload to perform some operation after the image has been loaded
onload:function(){FX not started yet but image loaded}

// optional reverse property over a completed liquid FX
reverse:true
});

New in version 1.3, the Liquid function returns the configuration object and it adds two methods: pause and play.
Specially pause is useful to stop FX if we need to clean the target container.
// pause/play example
var lq = Liquid({
src:"mycoolimage.gif",
target:document.body,
onload:function(){
setTimeout(function(){
lq.pause();
setTimeout(function(){
lq.play();
}, 500);
}, 500);
}
});


This is pretty much it, so far. I am planning to implement a LiquidReversed function as well, in order to let the images disappear in the same way they appear.
The source code with Mit Style License is here while the inspiration is from my 2005 ActionScript 1 imageStretcher code.

enjoy

Wednesday, September 16, 2009

I Would Simply Like To Support iPhone But I Cannot

Update
Before other silly flame/blame will start, I have already twitted that my next laptop will be a netbook. Here the related tweet.


let me summarize the story: at that time I had a girlfriend with an iPhone so I though why on earth shouldn't I buy an Android instead? If I need some test online I'll have both to test it, and I've rarely been that wrong.

Wanna Develop for iPhone? Buy a Mac

As marketing strategy sounds "cool" except I do not want to develop iPhone application, the present and the future is online, why on earth should I learn another programming language from the scratch, Objective-C, to develop something that will be relatively soon replaceable via WebKit and a good host?

Wanna Develop Web for iPhone? Buy a Mac

Again!!! Unbelievable, there is not such a thing: online iPhone tester, everything I found Googling was about a silly image with an iframe just to test the iPhone size ... are you kidding me?
It's like put IE inside an iframe inside an "Android frame" ... where is webkit? Where is the real JS engine? Where is the real render engine?

Wanna Develop for Apple Devices? Buy Apple

OK, I got your point, so now I am stuck with an Android contract and moreover I "love" my Android and it's about a year I am using it writing at light speed thanks to hidden keyboard, and using for whatever Web purpose thanks to its WebKit which is maybe not perfect but it works like a charm, generally speaking.
I do not want to buy a Mac only to test iPhone Web engine via Xcode, I'd love to have better reasons for a Mac, and I don't want to buy an iPhone only to test it online.
That will mean another contract to surf the Net as well ... and why on earth should I do this while I am simply trying to support iPhone?

I Would Simply Like To Support iPhone But I Cannot

Now I am a single developer, but I cannot imagine all other engineers, JavaScript hackers, W3C "slaves", cross-browser maniacs, unable to develop a web application for iPhone. With this strategy Apple is missing the possibility to fix a wider range of problems related to iPhone WebKit dedicated build and moreover it is avoiding iPhone Web support for "silly developers" like me that in this case was only trying to fix a common problem, the css position fixed property, but I am unable to make it works in an iPhone while every other A-Grade browser is supported, Android included, and here is the example!

As Summary

People like Peter-Paul Koch have the privilege to try any kind of mobile device in order to test compatibility. Unfortunately for Mobile Devices Vendors Peter-Paul alone will never be able to cover every kind of test. Even Microsoft releases time bombed images for Virtual Machines in order to test other versions of Internet Explorer. The Android OS is Open Source and it is possible to test it almost via whatever platform, same is for other browsers but not the iPhone. I know you do not mind but you are missing my contribute and support for projects a la sessionStorage, Formaldehyde, the incoming position-fixed, vice-versa or noSWFUpload ... and again, I am only one out of million of web developers.

Please think about it,
Best Regards

Monday, September 14, 2009

LiveMonitor - Asynchronous Property Monitor

Today I would like to introduce you a quite uncommon JavaScript trick, a trapped Live Object or, generally speaking, a lightweight monitor able to understand when a generic property has been changed.

About Live Objects

A live object could be described as a particular object able to change without our interaction. The most common live object example is this:

// this is the most common live object
// the HTMLCollection
var divs = document.getElementsByTagName("div");
divs.length; // let's say 4

// let's add another div inside a generic node
document.body.appendChild(
document.createElement("div")
);

divs.length; // 5!

In few words DOM searches are dynamic, which is the reason almost every selector library needs to transform the current result into a static Array.

About LiveMonitor

Specially suited for live objects, LiveMonitor is a function which aim is to notify us when the specified property change:

// LiveMonitor example
var lm = new LiveMonitor(
// the entire list of elements trapped
document.getElementsByTagName("*"),
// the property to monitor
"length"
);

// add one or more notifier
lm.onchange(function(collection){
// this, will be the lm object
this.value; // will be collection.length
collection.length; // is the new length

alert([
"All nodes collection contained ",
this.value,
" nodes but now there are ",
collection.length
].join("\n"));
});

The example is quite silly, but the concept is that as soon as the monitor will check the "length" property, in this case in the one of the trapped collection, it will fire the onchange event, notifying us that somebody did something somewhere, and this something changed our monitored property.

LiveMonitor Code


var LiveMonitor = (function(){

/** LiveMonitor :: Asynchronous Property Monitor
* @author Andrea Giammarchi
* @license Mit Style
* @blog http://WebReflection.blogspot.com/
*/

function LiveMonitor(object, property){
this.value = object[property];
this._property = property;
this._object = object;
this._event = [];
this._i = 0;
};

LiveMonitor.prototype.onchange = function onchange(callback){
this._event.push(callback);
if(this._i === 0){
var _property = this._property,
_object = this._object,
_event = this._event,
self = this
;
this._i = setTimeout(function _i(){
if(self.value !== _object[_property]){
for(var i = 0, length = _event.length; i < length; ++i){
if(_event[i].call(self, _object) === false)
break
;
};
self.value = _object[_property];
};
if(0 < self._i)
self._i = setTimeout(_i, 15)
;
}, 15);
};
};

LiveMonitor.prototype.offchange = function offchange(callback){
for(var _event = this._event, i = 0, length = _event.length; i < length; ++i){
if(_event[i] === callback)
_event.splice(i, 1)
;
};
if(_event.length === 0){
clearTimeout(this._i);
this._i = 0;
};
};

LiveMonitor.prototype.clear = function clear(){
this._event = [];
this.offchange(null);
this.value = this._object[this._property];
};

return LiveMonitor;

})();


Not Only DOM Searches

LiveMonitor could be actually used as asynchronous notifier for any kind of variable.
Let's say we have an environment able to load runtime scripts but we cannot change loaded scripts (external source inclusion).
At some point we press the "load jQuery" button and we would like to be able to be notiied when it is available ...

if(!window.jQuery){

// create a LiveMonitor instance over
// jQuery property
var jqlm = new LiveMonitor(window, "jQuery");

// add onchange event
jqlm.onchange(function(window){

// remove this event
this.offchange(arguments.callee);
// remove jqlm as well, it is not useful
// anymore for this example

// use jQuery, it's here for sure!
$("body").html("Hello LiveMonitor!");
});

// load external script
loadScript("http://external/jQuery.js");
};


Conclusion

With a cross-browser, portable, and lightweight function, we can use notifications without effort over objects, HTMLCollections, Arrays, or everything else we would like to monitor. Let's say this is a sort of asynchronous cross browser Object.prototype.watch, but this time without alchemy.

Thursday, September 10, 2009

Formaldehyde JS - The Circle Is Close

As announced in Ajaxian, I have created Formaldehyde JS with exactly the same Zero Config logic.

We put this file before everything else and that's it, Formaldehyde will automatically decide how to show errors in a wide range of browsers:
  • Chrome
  • Firefox
  • Internet Explorer 5, 5.5, 6, 7, 8 with or whout console
  • Opera
  • Safari

Logs will naturally degrade until the most primitive alert but hey, Formaldehyde is for debug and development environments, not for production.

Enjoy ;)

Wednesday, September 09, 2009

double tweet - up to 280 chars tweets!

Update
At least one other person did the same and before this post, here there's the prove.
The algo seems to be almost the same, except the length is probably padded to be module of 2 (\x00 at the end) so you can use double-tweet gadget to decode gareth message as well :)


Via encode template and same bookmark link, I would like to introduce my last simple experiment: WebReflection::double-tweet (just a click to give it a try, another one to remove)

The Concept

Twitter lets us type messages with a maximum of 140 characters. Fortunately, twitter accepts Unicode characters and still fortunately, it is extremely easy to pack two ASCII characters into a single Unicode one. Accordingly, 140 ASCII characters could be packed into 280.

A Fast ASCII pack / unpack

function ASCIIPack(s){
// WebReflection Mit Style License
for(var r = [], i = 0, length = s.length, c; i < length; ++i){
c = s.charCodeAt(i);
r.push(++i < length ? (c << 8) + s.charCodeAt(i) : c);
};
return String.fromCharCode.apply(String, r);
};

function ASCIIUnpack(s){
// WebReflection Mit Style License
for(var r = [], i = 0, length = s.length, c; i < length; ++i){
c = s.charCodeAt(i);
0xff < c ? r.push(c >> 8, c & 0xff) : r.push(c);
};
return String.fromCharCode.apply(String, r);
};
The main reason my code could be faster than others common de/encoder, is the usage of apply over a single String.fromCharCode call. You can try to pack and unpack massive documents but please do not forget I am using this for twitter ;)

Safe Pack - What Is It

I have already tested this technique for a 280 tweet but instantly I realized that except some geek one able to decode the message, nobody could receive, understand, or be involved in that tweet. In few words, I somehow killed twitter beauty, concept, and that is why I have added a safe option.
Basically, targets, specified via @target, keys, specified via #key and urls are preserved by defaults. It is still possible to disable this feature and send a 280 ASCCI characters tweet, but I think it does not make much sense.

About Searches Or Search Engines

Being a tweet search inevitable small, all we need to look for is a combination of the clean word, plus the packed one, trying with and without a space before to be sure that word has not been encoded in a different way. Moreover, if for some reason twitter will implement this search option, something I honestly do not think at all, its internal conversion will be still fast, assuming the search is performed via binary match and that the unpack option is that simple/fast (I know, we are talking about billions or records, that is why I think they'll never do it)

Conclusion

If I am not late with this double-tweet idea, I guess we can add the sixth way to send more than 140 characters via twitter :)

P.S. if you pass a link with some text after the anchor, it will be automatically put in the text area

P.S.

As somebody suggested, with few changes the function could theoretically pack 3 ASCII in a range 0 - 0xFFFFFF (3 bytes per char, UTF-8)
The problem is that JavaScript supports mainly range 0 - 0xFFFF so there is no point to even write down the function ;)

Monday, September 07, 2009

PHP Serialization And Recursion Demystified

Introduction

PHP has different in-core callbacks able to help us with daily deployment, debug, improvements. At the same time, PHP is loads of intrinsic "gotcha", too often hard to understand, hard to explain, or simply hard to manage. One common problem is about debug, caching, or freezing, and the way we would like to debug, cache, or freeze, variables.
For freezing, I mean those procedures able to regenerate a stored variable and its status, in order to reuse that variable, to understand what happened in that moment with that variable, or just to speed up expensive tasks already completed.


The Problem

One of the most common procedures to freeze variables is their serialization, performed in core via a well known serialize function.
Please consider this example:

$person = new Employee('Mr. Lucky Me');
// ... do some useful task
myCompanyFreezer($person);

// the myCompanyFreezer function

function myCompanyFreezer(Employee $p){

$company = Company::getInstance();
// note that this company has exclusive
// control over the employee work (reference)
$company->employees[] = &$p;

// on the other hand employee
// has finally a company to work with
// but no control over the company
$p->company = $company;

// update and freeze the employee status
$company->add(serialize($p));
}

So, while company has an exclusive contract, and each employee is totally under company control, the employee has nothing to do with company decisions, but it can proudly say: "Look at me, I work for Company::getInstance()!".
But being serialization recursive, we will find the company instance present as employee "company" property.
The problem is that the company instance has an "employees" property which contain one or more employees, included the employee Mr. Lucky Me.
And so on and on until infinite recursions, a massive waste of resources and ... ALT!, serialize is clever enough to understand when there are recursions and rather than going on with nested serializations it simply put a reference to the serialized object.
Got headache already?

Two Different Kind Of Recursions

Being serialize main purpose to freeze a variable status, and being PHP still a bit hybrid about references and shadow copies, serialize could produce two kinds of pointer: r and R.
The lowercase "r" will be a recursion, while the uppercase "R" will be a recursion by reference.

// serialized recursion - the ABC
$o = new stdClass;

// recursion
$o->normal = $o;

// recursion by reference
$o->reference = &$o;

echo serialize($o);
// O:8:"stdClass":2:{s:6:"normal";r:1;s:9:"reference";R:1;}

We should focus into r:1; and R:1;.
While the "r", or the "R", means there is a recursion, the unsigned integer indicates the exact object that "caused" that recursion.
When we perform an unserialize operation, the parser cannot obviously de-serialize as we read, because if we have an instance or an array, internal values should be ready to be assigned already "unserialized".
This simply means that the number after the R is not sequential, and there is no relation with the length of the string, but only a relation with de-serialization process.

What Is WrongWith Serialize

First of all, PHP serialization is not human readable as JSON, as example, or an XML is.
If we use this format to debug our application we'll definitively need an extra layer able "to introduce" us the object as is. In few words, what we need is something that is not serialized.
Moreover, serialize and unserialize would like to be as much reliable as possible, and for these reasons these functions are 3 times slower than json_encode or json_decode.
The truth is that JSON, as is, cannot compete with serialize and unserialize, due to protocol simplicity which is unable to store class names, lambdas, or public, protected, and private instances properties.
Last, but not least, JSON PHP parsers are a bit ambiguous, because an array not fully populated is usually converted into an object:

define('MY_WELCOME_STRING', 1);
$a = array();
$a[MY_WELCOME_STRING] = 'Hello World';

echo json_encode($a);
//{"1":"Hello World"}

// in JavaScript would have been
// [null,"Hello World"]
// where square brackets mean Array, and not Object

So again, another serializer is not worth it to freeze variables, what's left for us?

var_export

var_export() gets structured information about the given variable. It is similar to var_dump() with one exception: the returned representation is valid PHP code.

EUREKA! There is a core level function which aims is to serialize PHP into valid PHP, how can we ask something more efficient? I mean: "native performances to serialize and native performances to have back, it must be the solution"!
It's not!

$o = new stdClass;
$o->normal = $o;

echo var_export($o);

Fatal error: Nesting level too deep - recursive dependency?

Nice one! From bogus 39116 and Derick reply:
We can't change this by adding some text when this happens, as that
would not result in valid PHP code in that case (which is the purpose of
this function
).

Let me summarize:
  1. serialize/unserialize understand recursions almost without problems but unserialize is slow and both are PHP dedicated

  2. json_encode is not compatible with recursion, and as general purpose PHP serializer, it looses too much PHP information
  3. var_export would be perfect but in PHP we cannot manually represent a recursion that will be valid and correctly parsed
  4. var_dump is magic but its produced output is not reliable, *RECURSION* won't be recognized as valid PHP value
  5. I had already headache at line 10 of this post, and now I am still here to see there are no solutions?


How To Remove Recursion Without Loosing It

Well, solutions are different, but performances speaking, we do not have too many chances. A first solution could be a maximum nested level limit, where an object cannot serialize its properties "forever" and after N times it has to stop!
This technique has more cons than pros, and reasons are these:
  • it could require a manual parser, slower, and due to the problem nature, not that simple to maintain or debug
  • it could be extremely redundant, causing a lot of wasted resources, due to its artificial stupidity, since a recursion should never be serialized, being indeed a recursion, and in this way a waste of time, references, and resources
  • as mentioned 5 words ago, in this way we are loosing the recursion, so we should stop saying we are serializing ...
Accordingly, there is only another chance to perform this task: understand recursions, and remove them without loosing their meaning.

$o = new stdClass;
$o->n = $o;
$o->r = &$o;

echo serialize($o), '
',
serialize(
remove_recursion($o)
)
;

Produced output:

O:8:"stdClass":2:{s:1:"n";r:1;s:1:"r";R:1;}
O:8:"stdClass":2:{s:1:"n";s:12:"?recursion_1";s:1:"r";s:12:"?Recursion_1";}

Et voilà! problem solved! ... but what is that?
The remove_recursion function has been introduced in latest Formaldehyde Project Version 1.05, and its purpose is to make debuggable any kind of trace, backtrace, or logged information.
The resulting var_export will be something like this:

stdClass::__set_state(array(
'n' => '' . "\0" . 'recursion_1',
'r' => '' . "\0" . 'Recursion_1',
))

The chosen form to store a recursion is exactly the same used by PHP for lambdas

echo serialize(create_function('',''));
//s:10:"?lambda_1";

In PHP a lambda is stored as "protected" string, and the number at the end of the string "lambda_" indicates its reference. Until we restart our webserver, lambda functions will persist in the entire PHP context, that is why it is possible to serialize lambda functions and unserialize them, as long as the environment does not change, or restart.
The additional difference between "r" and "R" in case of recursion is necessary to avoid info about references.
On the other hand, recursions are truly useless to debug or export variables, but they can always be present.
PHP will not understand my chosen syntax, but only and if necessary, we can always use a function like this to recreate correct recursions:

function recreate_recursion($o){
return unserialize(
preg_replace(
'#s:[0-9]+:"\x00(r|R)ecursion_([0-9]+)";#',
'\1:\2;',
serialize($o)
)
);
}


Pros

  1. we can finally forget every kind of recursion problem, letting PHP understand them via serialize, without doing anything
  2. performances and produced size will be better than every other nested based parser, thanks to a simple parser which ... surprise!!! ... it does not use recursion at all!
  3. once we pass a variable through formaldehyde_remove_recursion we can transform that kind of variable in whatever format, included var_export, JSON and XML, forgetting recursions headaches


Cons

  1. being based over serialize and unserialize, the transformation could implicitly call, if present, both __sleep and __wakeup events, it's gonna happen in any case if we use serialize/unserialize, but if we serialize a transformed variable __sleep will be called twice
  2. it could require extra effort to regenerate internal recursions, in any case it is better than loose them forever as most of us have done 'till now
  3. the convertion is assumining that a serialized string will not contain an exact match, such a manual string. This is actually the same assumption PHP developers did about serialized lambdas.


Conclusion

With a lightweight function, and after this post, I hope we can better understand recursion problems, and relative serializations. My suggestion is to give Formaldehyde a try, but as long as the Mit Style License is respected, you can extract its internal formaldehyde_remove_recursion.

Any question? :)

Sunday, September 06, 2009

PHP How to var_export a debug_backtrace

Just a quick post, and I am not sure if this is documented, or if this works with every PHP version, but apparently a truly common problem with var_export is the logical inability to manage recursions.

Well, one of the most important function in PHP is the debug_backtrace, which contain recursion, and one thing you would probably like to know is that this trick allowed me to avoid recursion problems:

$backtrace = unserialize(
serialize(debug_backtrace())
);

After this, it is possible to use json_encode, var_export, or whatever other serializer.
The reason is that serialization discover and remove some implicit recursion, so that unserialize will return a cleaner object.
This technique has been used in Formaldehyde, but manual recursions are not supported yet (for example via formaldehyde_log). recursions, for a debug purpose, are in any case redundant. All we need to know is what is there, rather than where.
Regards

Saturday, September 05, 2009

Formaldehyde - Ajax PHP Error Debugger

I am proud to announce my last Web 2.Next creation, Formaldehyde, the most simple, lightweight, scalable, and complete (for its simplicity) Ajax and PHP Error Debugger.
I described everything in its dedicated Google Code Project Page, but just to summarize without many other words, this is the common deployment situation:


while this is what's up with a single formaldehyde.php file inclusion:


I hope you will like it, can't wait for some comment :geek:

Friday, September 04, 2009

@font-face we are already doing wrong

Update - Now We Do Right

Thanks everybody for your tests and contributions. For those interested about why we were doing wrong please read both post and comments but for those just interested about the best way so far to serve correctly one or more font-face, this is the hack:

@font-face {
// define the font name to use later as font-family
font-family: "uni05_53";
// define the font for IE which totally ignores local() directive
src: url(../font/uni05/uni05_53.eot);
// use local to let IE jump this line and
// redefine the src for this font in order to let
// other clever browser download *only* this font rather than 2
src: local("uni05_53"), url(../font/uni05/uni05_53.ttf) format("truetype");
}

You can test directly this technique in my HTML5 Prime Directives Test Page



Credits

  • Paul Irish for its Bulletproof @font-face syntax

  • Mikuso, comments, for his suggestions about server configurations, instantly followed by Weston Ruter for its excellent article Efficiently Serving Custom Web Fonts

  • last, but not least, Scott Kimler, for his Better @font-face Syntax and his patience, testing directly inside a trace log, rather than trust 100% Fiddler or Firebug - P.S. my hat is off for that page, unfortunatly you have trolls problems as well, reading the first comment from somebody that got -1% of what you have done!
Links, snippets, tests, we have got everything we need to understand why font-face CSS plus file serving has been generally misunderstood and how we should do correctly, trolls included (the problem is not the browser).

Good Stuff!
Just last quick info for Scott Kimler, IE simply lacks "local" directive support, and this is the reason it ignores the second call.
If we put local(fontName), url(fontName.eot) it will not load the eot, neither the ttf - local is the key for this trick, but we'll have problems the day IE will understand local, unless the first src will not considered synchronous.
Hopefully, that day IE will support ttf since windows does already without problems.


Few weeks with new browsers and @font-face support that suddenly everybody started to suggest the "cross browser way" to include them ... which is 90% of cases apparently wrong.

The Wrong Way



/* IE first */
@font-face {
font-family: nomeDelFont;
src: url( /nomeDelFont.eot );
}

/* Firefox 3.5/Safari/Opera 10 */
/* but IE will download in any case */
@font-face {
font-family: nomeDelFont ;
src: url( nomeDelFont.ttf );
}

almost the equivalent showed here, via Ajaxian, and Edit ...

What Is Exactly Wrong


It does not matter if we use conditional comments, it does not matter if we put the right font for Internet Explorer before the other one (tricky, since IE does not overwrite the rule just because it does not understand the truetype format).

Our "favorite" browser, and others as well in some case, will always request the truetype as well, and being fonts not that lightweight, our page response could sensibly increase.

HTML5 Prime Directives


Inspired by RoboCop, I have created a simple test page that does not suffer the problem described before.
What we have there is an extremely compact and valid HTML5 page which size is up to 140Kb, and almost 67Kb just for the font.

Plus, as I've said, If we use common suggested snippets Internet Explorer will download in any case the non IE font, try yourself!

First Suggestions To Try To Solve The Problem



  1. never forget to specify the format, format("truetype"), which is apparently able to let IE misunderstand correctly the url and the result is a Error 404, still better than 70Kb to download

  2. moreover, use whatever strategy you know to avoid non IE file serving for IE as well (use Fiddler to monitor the network)

  3. try to create gzipped or deflated version of each font, possibly not runtime, and serve them via proper headers (69Kb down to 22Kb, as example, with 7Zip deflate)

  4. please tell us how you avoided IE wrong font download without using an horrible JavaScript document.write as I did in my little test page


Thanks, and I hope you agree about Prime Directives :D

Thursday, September 03, 2009

JScript Console - A Simple One

After I've read Ajaxian post about JavaScript as a command line scripting language I thought it could be interesting to know how to create the first Windows console.

The console.js File


function print(text){
WScript.StdOut.WriteLine(text);
};
function quit(){
WScript.quit(1);
};
while(!WScript.StdIn.AtEndOfStream){
try{
eval(WScript.StdIn.ReadLine());
}catch(e){
print(e.message);
};
};
WScript.StdOut.WriteLine("bye!" + "\r\n");


The console.bat Launcher


@echo off
cscript console.js

A double click in latter file, and that's it, the most basic native JScript console ever has landed in your PCs - enjoy :)

Wednesday, September 02, 2009

PHP 5.3 Singleton - Fast And Abstract

In this same blog I talked different times about Singleton Pattern, in latter link "poorly" implemented in PHP 5.

I say poorly, because being Singleton a pattern, there are many ways to implement it and via PHP 5.3 things are more interesting.

There are several ways to define a Singleton class and to extend it, being able to automatically create another one that will follow that pattern.

Here is my implementation, which is extremely fast, logic, and simple as well.

<?php // Singleton :: The WebReflection Way

namespace pattern;

// this is just a pattern ...
// so no new Singleton is allowed
// thanks ot abstract definition
abstract class Singleton {

// note, no static $INSTANCE declaration
// this makes next declaration a must have
// for any extended class
// protected static $INSTANCE;

// @constructor
final private function __construct() {
// if called twice ....
if(isset(static::$INSTANCE))
// throws an Exception
throw new Exception("An instance of ".get_called_class()." already exists.");
// init method via magic static keyword ($this injected)
static::init();
}

// no clone allowed, both internally and externally
final private function __clone() {
throw new Exception("An instance of ".get_called_class()." cannot be cloned.");
}

// the common sense method to retrieve the instance
final public static function getInstance() {
// ternary operator is that fast!
return isset(static::$INSTANCE) ? static::$INSTANCE : static::$INSTANCE = new static;
}

// by default there must be an inherited init method
// so an extended class could simply
// specify its own init
protected function init(){}

}

?>


The static Trick


static is a magic keywords able to open hundreds of closed doors with old PHP versions. Thanks to this keyword it is possible to avoid a lot of redundant code, being sure that when static is called, it will be the current class call and not the one where self has been used. Thanks to this keyword is then possible to refer directly the current class instance, the one that will extend pattern\Singleton, using its own init method if preset, the empty abstract inherited otherwise.

Example



<?php

// for this test only, this class
// is in the root, same level of autoload.php

// include basic stuff ...
require_once 'autoload.php';

// define a singleton class
class SingA extends pattern\Singleton {

// my Singleton requires a
// protected static $INSTANCE variable
// if not present, nothing will
// be executed - Fatal error
protected static $INSTANCE;

// let's define something else
protected $a = 'A';
protected $b;

// let's try the init method
protected function init(){
// assign a random value to b
$this->b = rand();
}
}

// define another singleton class
class SingB extends pattern\Singleton {
protected static $INSTANCE;
}

// let's try the Singleton
$sa = SingA::getInstance();
$sb = SingB::getInstance();
$sb->runTime = 'here I am';
$sa2 = SingA::getInstance();

echo '<pre>',
var_dump($sa),
var_dump($sb),
var_dump($sa2),
var_dump($sa === $sa2),
var_dump($sa !== $sb),
'</pre>'
;

?>

Above test case will produce exatly this output:

object(SingA)#2 (2) {
["a":protected]=>
string(1) "A"
["b":protected]=>
int(31994)
}
object(SingB)#3 (1) {
["runTime"]=>
string(9) "here I am"
}
object(SingA)#2 (2) {
["a":protected]=>
string(1) "A"
["b":protected]=>
int(31994)
}
bool(true)
bool(true)

assuming the file autoload.php is present in the same level:

<?php

// simple autoload function
spl_autoload_register(function($class){

// assuming this file is in the root
// (just as example)
require __DIR__.
DIRECTORY_SEPARATOR.
// fix namespace separator ...
str_replace(
'\\',
DIRECTORY_SEPARATOR,
$class
).
// add classes suffix
'.class.php'
;
});

// that's it

?>


Why This Is Faster, Why This Is Better


The reason I posted about my own PHP 5.3 implementation is a php mailing list discussion which pointed to another extended Singleton for PHP 5.3.
That implementation will perform for each getInstance() call a callback which aim is to discover the class caller, get_called_class(), plus 2 up to 3 lookups plus an assignment over a static associative array, self::$instance[$class].
Finally, even if it could not make sense, extended Singleton classes cannot access to their own Singleton instances, aka: less control and overhead being Singleton a truly common pattern.
At least you know there is an alternative which aim is to let us remember that a singleton is a unique instance, the one we need to define as protected $INSTANCE, and that performances are always welcome, at least in my daily code/life style.

Enjoy!

Tuesday, September 01, 2009

94 bytes to quickly get a var type

I surpassed myself for the third time but I tweeted too much about, so here a quick one ;)

// was getClassName but people prefer type
// while kangax prefers var
var type=(function(s,u){return function(o){return o==u?""+o:s.call(o).slice(8,-1)}})({}.toString);