<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearchrss/1.0/" xmlns:georss="http://www.georss.org/georss" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0"><id>tag:blogger.com,1999:blog-34454975</id><updated>2009-07-17T16:21:29.069+02:00</updated><title type="text">Web Reflection</title><subtitle type="html">behind the design</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://webreflection.blogspot.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default?start-index=26&amp;max-results=25" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>281</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><link rel="self" href="http://feeds.feedburner.com/WebReflection" type="application/atom+xml" /><entry><id>tag:blogger.com,1999:blog-34454975.post-6036388460356564157</id><published>2009-07-16T21:22:00.006+02:00</published><updated>2009-07-16T22:18:04.987+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="italia.it" /><title type="text">[IT] ri-italia.it, parere veloce veloce</title><content type="html">Come benvenuto abbiamo una pagina dal leggero peso di 588Kb, per un'immediata impressione di lentezza pachidermica ed un loading time da 1 minuto e 13 secondi su un totale di 72 inutili richieste.&lt;br /&gt;&lt;br /&gt;Se togliamo le immagini, le immagini appese in seguito via jQuery e/o plugins, e il filmatone flash che non poteva mancare, praticamente è una pagina bianca: perchè noi italiani non abbiamo niente da dire, basta mostrare la faccia e la firma del nostro presidente per far si che chiunque possa capire al primo sguardo di che pasta è fatta l'italia odierna.&lt;br /&gt;&lt;br /&gt;Pratiche stra note per ottimizzare il sito nemmeno una, in compenso una sfilza infinita di javascript per jQuery più non so quanti plugins tutti usati su un file unico per un evento onReady che farebbe piantare i PC più datati non appena la pagina è stata caricata. (per i trolls: c'è il mio nome nei sorgenti di jQuery quindi so di cosa sto parlando)&lt;br /&gt;&lt;br /&gt;Stesso discorso per i css: a quanto pare siamo così avanti che YUI Compressor in build sia per l'unico javascript che per l'unico CSS, ad eccezione dei due per IE6 ed IE7, era chiedere troppa tecnologia ... tanto più che la sfilza di css e js è sistematica, qualunque pagina stiamo navigando.&lt;br /&gt;&lt;br /&gt;Questo in aggiunta all'ammontare imbarazzante di "immagini ed immaginine", più il filmatone flash, più tutti i commenti nella pagina degni del framework più superficiale incapace di rimuovere commenti assolutamente inutili e per di più con tempi ridicoli, se quelli sono i tempi (0.4 secondi per un unico modulo da quattro immagini in croce ... complimenti per il framework utilizzato) servono a ricordarci quanto la situazione ADSL in Italia sia ridicola con una penetrazione ancora insufficiente.&lt;br /&gt;Ma a noi che stiamo bene non ce ne può fregare di meno!&lt;br /&gt;&lt;br /&gt;Con questo Welcome, il tasto in fondo con scritto Accessibilità l'ho evitato in pieno poichè non c'è bisogno di arrivare a cliccarlo per capire che il contenuto della pagina accessibilità avrà probabilmente la dicitura:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;&lt;strong&gt;Accessibilità&lt;/strong&gt;&lt;br /&gt;Stiamo cercando di comprendere meglio cosa diavolo significhi.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;e niente altro, dato che persino Magic Italy, la rivista, suppongo pensata per il resto del mondo, richiede flash player, senza navigazione tab based, e anch'essa ovviamente pesantissima.&lt;br /&gt;&lt;br /&gt;Dato che c'erano dei testi oltre al PDF e le immagini dei PDF da mostrare in modo così advanced, potevano metter i testi nel sito in modo da essere facilmente letti ed indicizzati anche da motori di ricerca stranieri? &lt;strong&gt;utopia&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;Vado su Marche, la mia mata regione, e noto subito che le sotto sezioni non sono indicizzate a modo (briciole inutili) se non nella mappa del sito ... e vabbèh, almeno quella!&lt;br /&gt;Filmatone solito in flash ed un avviso prima di mostrarlo: &lt;em&gt;per vedere questo filmato devi installare il seguente plug-in Adobe Flash player&lt;/em&gt; ... vado quasi per clickare quand'ecco che il filmatone appare ... meglio così, ce l'avevo già!&lt;br /&gt;&lt;br /&gt;La descrizione non è legata al filmato, comunque grazioso.&lt;br /&gt;Siccome vivo e lavoro qui a Londra mi son detto: proviamo la versione inglishhhhh ... clicko inglishhhh ed ecco che riappare l'avviso di prima, ovviamente sempre in italiano:&lt;br /&gt;&lt;em&gt;per vedere questo filmato devi installare il seguente plug-in Adobe Flash player&lt;/em&gt; ... &lt;strong&gt;Excuse Me?&lt;/strong&gt;&lt;br /&gt;Almeno il resto sembra essere in inglese, ma anche dopo questa visita veloce, Accessibilità è ancora una parolona grazie ad errori così banali impensabili con 10 milioni di euro come commissione.&lt;br /&gt;&lt;br /&gt;Siccome continuo a vedere in Firebug, il fantastico plugin per il &lt;a href="http://www.mozilla-europe.org/it/"&gt;browser Firefox&lt;/a&gt;, che il template di testata è praticamente statico mi domando: ma porca miseria già che non hanno usato i giusti headers sopra un unico file per agevolare almeno il caching di tutti quegli scripts tramite un unico file, mi fai vedere che diavolo modificano tutti questi files?&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;javascript:(function($,r){window.$=function(){r=$.apply(null,arguments);alert(r.length);return r}})($);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Copiando ed incollando questo banalissimo script sulla barra degli indirizzi mentre la pagina sta caricando e dopo che jQuery è stata scaricata (al primo script tag caricato dopo jQuery ne siamo praticamente certi) avrete un alert per ogni chiamata alla libreria e/o plug-in utilizzato.&lt;br /&gt;Ebbene, tutti quegli zero che vi si pianteranno davanti uno dopo l'altro sono l'insieme degli inutili plug-in messi li "per fare mucchio" e per creare un unico file di gestione client qualunque sia la pagina.&lt;br /&gt;In soldoni, non avendo utilizzato pratiche comuni di speed up, e &lt;a href="http://www.websiteoptimization.com/services/analyze/"&gt;qualunque tool serio ve lo può dimostrare e spiegare&lt;/a&gt;, ancora mi chiedo se a creare il sito sia stato un team di webbisti della domenica o se ci sia qualche ingegnere con carenze tecniche a dirigere questo team.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Conclusione&lt;/h3&gt;&lt;br /&gt;Non riesco a capire se sia meglio o peggio dell'altro ma sicuramente è tecnicamente più semplice (di qui tempistiche più normali).&lt;br /&gt;Meno sezioni, meno sotto sezioni, meno contenuti, credo stesse immagini probabilmente ri-sfruttare, che andrebbe anche bene, ma una serie di pratiche non dico amatoriali ma poco ci manca ... tutto questo non giustifica un investimento di 10 milioni di euro, opinione assolutamente personale.&lt;br /&gt;&lt;br /&gt;Personale non è invece il report di Web Page Analyxer:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;strong&gt;Download Times*&lt;/strong&gt;&lt;br /&gt;Connection Rate Download Time&lt;br /&gt;14.4K           940.07 seconds&lt;br /&gt;28.8K           493.13 seconds&lt;br /&gt;33.6K           429.29 seconds&lt;br /&gt;56K             276.05 seconds&lt;br /&gt;ISDN 128K       116.59 seconds&lt;br /&gt;&lt;strong&gt;T1 1.44Mbps     52.31 seconds&lt;/strong&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Analysis and Recommendations&lt;/h3&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;TOTAL_HTML - Congratulations ... e ti credo, come ho già detto ci sono zero contenuti da indicizzare&lt;/li&gt;&lt;br /&gt;&lt;li&gt;TOTAL_OBJECTS - &lt;strong&gt;Warning!&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;TOTAL_IMAGES - &lt;strong&gt;Warning!&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;TOTAL_CSS - &lt;strong&gt;Warning!&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;TOTAL_SIZE - &lt;strong&gt;Warning!&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;TOTAL_SCRIPT - &lt;strong&gt;Warning!&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;Questa volta i nomi degli autori/responsabili li abbiamo?&lt;br /&gt;&lt;br /&gt;P.S. Bisogna essere obiettivi su un fatto reale: &lt;strong&gt;Magi Italy&lt;/strong&gt; è lo slogan più azzeccato della storia.&lt;br /&gt;Come facciamo sparire i soldi noi, nemmeno David Copperfield ci riesce!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-6036388460356564157?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/6036388460356564157/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=6036388460356564157" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6036388460356564157" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6036388460356564157" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/kCyv_Hsc4Cw/it-ri-italiait-parere-veloce-veloce.html" title="[IT] ri-italia.it, parere veloce veloce" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/07/it-ri-italiait-parere-veloce-veloce.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-335436214320665264</id><published>2009-07-15T22:00:00.002+02:00</published><updated>2009-07-15T22:26:20.939+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JSON" /><category scheme="http://www.blogger.com/atom/ns#" term="Date" /><category scheme="http://www.blogger.com/atom/ns#" term="cross-browser" /><category scheme="http://www.blogger.com/atom/ns#" term="fast" /><title type="text">The Fastest Date toJSON and fromJSON?</title><content type="html">I know yesterday post supposed to be the last 'till the the end of the month but I could not resits. Dustin Diaz twitted&lt;br /&gt;&lt;blockquote&gt;&lt;br /&gt;anyone trying to parse our wonky rails dates in JS. do this: var date = Date.parse(str.replace(/( \+)/, ' UTC$1')); seems to fix it.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;Again, I could not resist to create a toUTCString based function to create JSON strings and to parse them back. This is the result and apparently is both the fastest implementation I know and cross browser (Chrome, Firefox, Inernet Explorer, Safari).&lt;br /&gt;This is a quick post so if you find some problem please let me know, thanks.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;(function(){&lt;br /&gt;// WebReflection Fast Date.prototype.toJSON and Date.fromJSON Suggestion&lt;br /&gt;var rd  = /^.{5}(\d{1,2}).(.{3}).(.{4}).(.{2}).(.{2}).(.{2}).+$/,&lt;br /&gt;    rs  = /^(.{4}).(.{2}).(.{2}).(.{2}).(.{2}).(.{2}).+$/,&lt;br /&gt;    d   = new Date,&lt;br /&gt;    f   = /(GMT|UTC)$/.exec(d.toUTCString())[1]&lt;br /&gt;    m   = {},&lt;br /&gt;    i   = 0,&lt;br /&gt;    s   = ""&lt;br /&gt;;&lt;br /&gt;d.setUTCDate(1);&lt;br /&gt;while(i &amp;lt; 12){&lt;br /&gt;    d.setUTCMonth(i);&lt;br /&gt;    m[s = /^.{5}(\d{1,2}).(.{3})/.exec(d.toUTCString())[2]] = ++i &lt; 10 ? "0" + i : i;&lt;br /&gt;    m[m[s]] = s;&lt;br /&gt;};&lt;br /&gt;Date.prototype.toJSON = function(){&lt;br /&gt;    var e = rd.exec(this.toUTCString());&lt;br /&gt;    return e[3].concat("-", m[e[2]], "-", e[1], "T", e[4], ":", e[5], ":", e[6], "Z");&lt;br /&gt;};&lt;br /&gt;try{Date.fromJSON(d.toJSON());&lt;br /&gt;Date.fromJSON = function(s){&lt;br /&gt;    var e = rs.exec(s);&lt;br /&gt;    return new Date(Date.parse(e[2].concat(" ", e[3], " ", e[1], " ", e[4], ":", e[5], ":", e[6], " ", f)));&lt;br /&gt;};&lt;br /&gt;}catch(e){&lt;br /&gt;Date.fromJSON = function(s){&lt;br /&gt;    var e = rs.exec(s);&lt;br /&gt;    return new Date(Date.parse(e[3].concat(" ", m[e[2]], " ", e[1], " ", e[4], ":", e[5], ":", e[6], " ", f)));&lt;br /&gt;};&lt;br /&gt;}&lt;br /&gt;})();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Basically everything is a shortcut and I am using only native methods ... is there anything faster except probably a substr based one?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-335436214320665264?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/335436214320665264/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=335436214320665264" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/335436214320665264" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/335436214320665264" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/ti4CFJjgbRs/fastest-date-tojson-and-fromjson.html" title="The Fastest Date toJSON and fromJSON?" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/07/fastest-date-tojson-and-fromjson.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-6553511498958866045</id><published>2009-07-14T21:10:00.005+02:00</published><updated>2009-07-14T23:11:41.424+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="delirium" /><category scheme="http://www.blogger.com/atom/ns#" term="crystal" /><category scheme="http://www.blogger.com/atom/ns#" term="ball" /><category scheme="http://www.blogger.com/atom/ns#" term="future" /><category scheme="http://www.blogger.com/atom/ns#" term="technologies" /><title type="text">[Webadamus] First Delirium</title><content type="html">&lt;h3&gt;Introduction&lt;/h3&gt;&lt;br /&gt;How many times we read news and we think "&lt;em&gt;I knew it was going to happen!&lt;/em&gt;"?&lt;br /&gt;How many times we think about a revolutionary project and few days before we are ready to introduce it to the rest of the world somebody, often with more money invested, introduced the same concept but with famous name behind and taking all the glory over that idea?&lt;br /&gt;Which developer interested about Web, reading about ex-imminent Internet Explorer 8, thought "&lt;em&gt;come on, it's Microsoft, we all know they have no interest to create a truly advanced browser, 'cause Internet with more power inside a browser could make an Operating System partially obsolete&lt;/em&gt;"?&lt;br /&gt;And who was truly surprised about Google OS announcement?&lt;br /&gt;&lt;strong&gt;Webadamus&lt;/strong&gt; will be a periodic Web Crystal Ball post here in WebReflection. It will talk about visions, thoughts, prototypes, and everything related to the future of the web and the most important thing is that &lt;strong&gt;everything will be just my imagination and nothing else&lt;/strong&gt;. Are you laughing? Are you interested? It's just an experiment, let's see in few months or years, if I was right, are you with me? Let's start then with my first delirium!&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Twitter: What's Next&lt;/h3&gt;&lt;br /&gt;The real potential of this famous service is almost unlimited, except for its 140 characters which, as limit, simply means they can manage more information than every other search engine. Gigabytes speaking, a tweet is meaningless while a web page size could be the equivalent of 100 tweets. And you know what? In a search engine what is important is the chosen title, the content, how much this site is paying to be in pole position, how much this site is spamming links around the net, etc etc ... In twitter, if search a subject selecting meaningful keywords, you will find only people truly interested in that website and for this reason, they re-twitted it. Waist of time? Almost zero, you search by people comments, you do not search by money and advertisement. Popular web sites? THey will be there ... crappy website? They will be &lt;strong&gt;unrated&lt;/strong&gt;. But what is going on behind the tweet fuss?&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;blacktwit&lt;/h4&gt;&lt;br /&gt;It could become an integrated service, or it could become simply a third part one, related via API. The blacktwit will contain the classic black list of twitter users. As virus, there are robots or malicious users which only aim is to create fakes account in order to pump up replies, followers, and followed. These users will be able to follow us as well, studying our messages, and in the worst case scenario, spamming/scamming any sort of website. Being twitter the place where url are 80% masked by "&lt;em&gt;url minifier web services&lt;/em&gt;", 30% of us will click that link and what's next does not matter, their mission has been completed. Thanks to blacktwit, our favorite twitter application will be clever enough to discard every message automatically or to ask us if we trust that user.&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;twitcode&lt;/h4&gt;&lt;br /&gt;I personally posted a couple of "twitcodes", almost complete web programming scripts in less than 140 characters ... but this is not what I mean. twitcode will be a service which aim is to send and recieve instantly quick reviews and votes about a product. #801245632+ will mean that the product in the shop or supermarket with bar code 801245632 has been appreciated while "-" at the end will mean the buyer did not like it. "&lt;em&gt;#801245632- no batteries included&lt;/em&gt;" will be a minus plus a comment. #801245632= will return number of users, and how many of them appreciated that product. Example: 10 users with that product, 6 appreciated it, the hash twitcode robot will reply 6/10 plus eventually a random comment, so if we do not like that comment we can tweet again and read the next. At the same time, this service will automatically have a database of interests and opinions in real time, something extremely important for any marketing purpose.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Private Services&lt;/h3&gt;&lt;br /&gt;As long as our twits are public we cannot use the hash too much. Here is where clever companies will create better robots able to manage private messages.&lt;br /&gt;&lt;em&gt;&lt;strong&gt;d twitdeal&lt;/strong&gt; #insurance Grande Punto 1.3 Split&lt;/em&gt;&lt;br /&gt;will be a direct message to user twitdeal that will instantly return the best option for that car while "d twitshop #price Asus 1101HA" will return the best price and the website for that product. It's all about fantasy and nothing else, but a quick service that does not require time neither thousands of pages to visit is a key for a quick future in this "everything in your hands" era.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Internet Explorer 9 Will Be Advanced&lt;/h3&gt;&lt;br /&gt;Microsoft, the most farsighted company during good old 90s, is loosing market share day after day. Slowly, slightly, but this is simply what is going on or, for sure, what everybody feels about this name. Innovation, does not exists, Silverlight is an Adobe clone with some extra feature already present in Google Chrome with some Chrome Plugin, a la O3D. People excited by hardware acceleration, should simply watch latest WebKit video about &lt;a href="http://ajaxian.com/archives/3d-css-effects-with-safari-on-snow-leopard"&gt;Snow Stack&lt;/a&gt;. Nothing new, not a single strategy able to bring innovation. A "new" search engine which development is distributed for each country for gosh knows which reason.&lt;br /&gt;A browser which has desktop features like accelerators, and nothing else new enough for its purpose, surfing the Web, except some partially implemented feature a la Object.defineProperty, compatible 1/3 of what Firefox and Safari are able to do since ages with any kind of objects and via __defineProperty__ et similar. Latest news are about Office 2010 Online, something not even scheduled because it will never be innovative enough "thanks to missed Internet Explorer 8 features". If Silverlight will be a requirement, Office 2010 online will be, imho, a partial flop. Google has already done something better, and ages before. For these reasons, and many more, Microsoft at some point will realize that if next browser will not be better than next Operating System their market will fall down as never before. That is why Internet Explorer 9 will the probably the best browser so far, and not just a toy.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Google OS Will Fly High Later&lt;/h3&gt;&lt;br /&gt;Users are not ready yet ... Google manages big numbers but home users still want more than Web. Maybe because they do not know yet what Web has to offer, considering 50% or more are still using Internet Explorer. Maybe because they want do their business without internet, or maybe because they do not feel secure, thinking that their anti viruses beside probably some cracked software installed is more secure than an Operating System not affected by viruses and spyware at all (this theme will be in another Webadamus post).&lt;br /&gt;Anyway, as somebody already said, minimalist Linux distributions with just Firefox already exist, and it is not only Ubuntu.&lt;br /&gt;We all know that when there is Google name behind whatever market strategy, some how this will reach the goal.&lt;br /&gt;We all know that as is for Netbook, first Google OS devices ( shall we call them &lt;strong&gt;Gbook&lt;/strong&gt;s ? ) cannot cost more than 150 pounds.&lt;br /&gt;How can people otherwise realize that they cannot live without? It will be a winning strategy, but it will take about 2 years before truly relevant results.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Passwords, As We Know, Will Disappears&lt;/h3&gt;&lt;br /&gt;This is the last delirium from Webadamus, but it is just a logic consequence about passwords. Let's analyze facts before!&lt;br /&gt;More services we have, more our passwords are exposed. If a service lets us choose which password we prefer, most of the time will be the same for every service.&lt;br /&gt;I am not even considering all those websites where the word "security" is meaningless, able to be cracked in a couple of sql injections or via browsers bugs!&lt;br /&gt;How secret is a password? First of all, most common passwords are birthdays or anniversary dates. Sometimes these passwords are just names, swearing words, and 90% of the time these passwords contain only ASCII characters plus some number.&lt;br /&gt;The most secret place for different passwords, or those generated automatically via a super SHA1024 unique hash algorithm, is usually a post it in the monitor. Somebody that feels half an hacker was clever enough to hide his password under the keyboard, still with a post-it. My bank account asked me to choose a password, and a super secret password, so I had to attach another post-it somewhere to digit one pwd first, and the second one after ... brilliant!!! The problem is intrinsic ... if I need money from a cache point, I have to hide numbers I need to digit so mistakes are more frequent and everything is in any case monitored 24/7 by the cash point camera, top right or directly over my head ... brilliant! In the supermarket I have rarely seen somebody remove the pad to digit the card pin number, while everybody is transverse and could potentially check it. It is common sense to do not look somebody doing it, but &lt;strong&gt;security is an utopia&lt;/strong&gt;.&lt;br /&gt;A lot of web users complained about this system of user/password which is absolutely boring and which does not improve security a single bit. This is the reason OpenID exists, but obviously we like choice so these kind of services are numerous ... another flop!&lt;br /&gt;The concept is: please identify yourself to use this service, whatever service it is. In few years, we will all be a number, a product with a barcode, and we will all agree about this new system because everything will be more simple. The way to identify us? It could be a special universal key, card, passport, something we should check every second otherwise we will need to contact the unique number: 10&lt;br /&gt;Telling that our ID is lost, and blocking in real-time every device connected into the central database ... sounds scary, but it is the only solution we have to make things more simple, unless we do not want to live wolverine style in a wood maiden house in the middle of nowhere (sounds like an adventure, isn't it?)&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;As Summary&lt;/h3&gt;&lt;br /&gt;This post is not that technical at all, it could be partially obvious and partially hilarious but this will be probably the last until the end of July or first days of August. I am going back in Italy for my sister wedding, friends, food, and hopefully sea under the sun ... so, what a better occasion to be insulted while I am far away from this PC with this USB temporary broadband? Have fun with Webadamus!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-6553511498958866045?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/6553511498958866045/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=6553511498958866045" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6553511498958866045" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6553511498958866045" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/yuaMY1Wkkn0/webadamus-first-delirium.html" title="[Webadamus] First Delirium" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/07/webadamus-first-delirium.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-5529992178695691216</id><published>2009-07-12T15:22:00.007+02:00</published><updated>2009-07-12T19:52:13.145+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Sandbox" /><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Elsewhere" /><title type="text">Elsewhere - Sandboxes Have Never Been That Easy</title><content type="html">One of the most common problems in Web 2.0 Development, is the amount of libraries we can possibly include into a single project and conflicts these libraries could have.&lt;br /&gt;Some library is truly aggressive. It could change the entire behavior of each other lib present in the page via not-standard or future implementations of some global object prototype, such String, Object itseld, Array, or others.&lt;br /&gt;Since this is a well known problem, some library/framework can try to avoid conflicts in different ways. As example, jQuery has a noConflict method which aim is to make development as painless as possible ... but it is not always that simple. One of Elsewhere purpose is to connect a completely different and external scope into the main window, avoiding any sort of conflict a library with its global properties, functions, or prototypes, could have. First example:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;new Elsewhere(&lt;br /&gt;    "scripts/libs/jquery.1.3.2.min.js"&lt;br /&gt;).execute(function(ready){&lt;br /&gt;    // this scope is elsewhere in a perfectly clean environment.&lt;br /&gt;    // In this case jQuery will be manifested as global "$" function.&lt;br /&gt;    // To bring jQuery outside, we can use this sandbox parent reference&lt;br /&gt;    parent.jQuery = function(search, context){&lt;br /&gt;        // to make sure we do not search in an "empty" document,&lt;br /&gt;        // the one part of this sandbox, we pass the context&lt;br /&gt;        // if not present as parent.document&lt;br /&gt;        return $(search, context || parent.document);&lt;br /&gt;    };&lt;br /&gt;    &lt;br /&gt;    // we can call the ready callback&lt;br /&gt;    ready(parent.jQuery);&lt;br /&gt;},&lt;br /&gt;[ // one or more arguments to pass into Elsewhere function execution&lt;br /&gt;function($){&lt;br /&gt;&lt;br /&gt;    // let's do something on ready event&lt;br /&gt;    // please note there is no var in front of jQuery&lt;br /&gt;    // since it has been declared as global&lt;br /&gt;    jQuery(function(){&lt;br /&gt;        // we could use the argument as well&lt;br /&gt;        // since in this case it is exactly&lt;br /&gt;        // the same jQuery function&lt;br /&gt;        $("body").html("Here I Am");&lt;br /&gt;    });&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;]);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Confused? Please read more ;)&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Quick Answer: What Is A Sandbox&lt;/h3&gt;&lt;br /&gt;Every time we open a new window in our browser, the latter one creates a (almost)clean environment to run, if presents, each JavaScript file. The same happens for each tab, which means that if we define a &lt;em&gt;function Z(){}&lt;/em&gt; in tab a, this will not be present in tab b. Finally, same things happens inside frames or iframes as well. Each window, framed, tabbed, or not, will have then its own JavaScript environment and in JS world this is called &lt;em&gt;sandbox&lt;/em&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What Is Elsewhere&lt;/h3&gt;&lt;br /&gt;Elsewhere is a lightweight, less than 1Kb if minified and gzipped, almost fully cross-browser library (so far compatible with each browser I tested) able to create runtime a sandbox including zero, one, or more scripts. The first showed example, creates a sandbox including jQuery library and bringing its power outside the box.&lt;br /&gt;The important thing to understand, is that used function scope will be completely extraneous to the one the function itself has been created ... in few words, that scope will be elsewhere!&lt;br /&gt;Thanks to possibility to send arguments when this external function will be executed, and thanks to parent or top reference, it is possible to play between different scopes avoiding conflicts, creating bridges, loading JSONP, and more!&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// JSONP example&lt;br /&gt;new Elsewhere(&lt;br /&gt;    "http://mycoolservice.com?fn=parent.callback"&lt;br /&gt;);&lt;br /&gt;// that's it!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;About JSONP, via Elsewhere a response could be more than just a callback. It could be an entire different environment with runtime created bridges. Example:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// output produced by a generic REST service&lt;br /&gt;// myservice.server/name/WebReflection&lt;br /&gt;&lt;br /&gt;// a function which name is not a problem&lt;br /&gt;function getReferences(){&lt;br /&gt;    return userInfo.name + " has " + userInfo.posts + " posts";&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// a global object which name is not a problem&lt;br /&gt;var userInfo = {&lt;br /&gt;    name:"WebReflection",&lt;br /&gt;    site:"http://webreflection.blogspot.com/",&lt;br /&gt;    posts:12345&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// a bridge for Elsewhere instance&lt;br /&gt;// every Elsewhere sandbox has a reference to its isntance&lt;br /&gt;// This reference is retrieved via global sandbox window object&lt;br /&gt;// and the property @_Elsewhere&lt;br /&gt;window["@_Elsewhere"].getUserProperty = function(name){&lt;br /&gt;    return userInfo[name];&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// please note you cannot access that property directly&lt;br /&gt;// window.@_Elsewhere will cause an error&lt;br /&gt;window["@_Elsewhere"].getReferences = getReferences;&lt;br /&gt;&lt;br /&gt;// ... &lt;br /&gt;&lt;br /&gt;// our main page via Elsewhere&lt;br /&gt;var myservice = new Elsewhere("myservice.server/name/WebReflection");&lt;br /&gt;myservice.execute(function(fn){fn()}, [function(){&lt;br /&gt;    alert(myservice.getUserProperty("site")); // http://webreflection.blogspot.com/&lt;br /&gt;    alert(myservice.getReferences()); // WebReflection has 12345 posts&lt;br /&gt;}]);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Understanding execute Method: How Elsewhere Works&lt;/h3&gt;&lt;br /&gt;How can be possible that a function defined inside a scope is totally ignorant about surrounding variables or scopes? It is really simple!&lt;br /&gt;Elsewhere is based on Function.prototype.toString de-compilation, creating passed function directly as script inside the sandbox and returning, if status is ready, its value or undefined.&lt;br /&gt;The important thing to understand is that if we create a global scope variable, this will be present next call, whenever we decide to perform it.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;var sb = new Elsewhere();&lt;br /&gt;// sb.ready is true, no external scripts loaded&lt;br /&gt;alert(sb.execute(function(){&lt;br /&gt;    // generic function&lt;br /&gt;    function sum(a, b){&lt;br /&gt;        return a + b;&lt;br /&gt;    };&lt;br /&gt;&lt;br /&gt;    // define sum as global in this scope&lt;br /&gt;    window.sum = sum;&lt;br /&gt;&lt;br /&gt;    // test the function&lt;br /&gt;    return sum(1, 2);&lt;br /&gt;&lt;br /&gt;})); // will be 3&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// do other stuff and ...&lt;br /&gt;sb.execute(function(){&lt;br /&gt;    return sum(3, 4);&lt;br /&gt;}); // will be 7, sum was already defined&lt;br /&gt;&lt;br /&gt;alert(typeof sum); // undefined&lt;br /&gt;// sum exists only Elsewhere&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;About the ready status flag, it is instantly true if we do not load external script, while it could be true or false, depending on which browser we are using (in some browser an iframe document with external scripts is loaded sync while with Firefox 3.5 an iframe does not block main page content so it is not sync).&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// more than a file ...&lt;br /&gt;new Elsewhere([&lt;br /&gt;    // order is respected and reliable&lt;br /&gt;    "jquery.js",&lt;br /&gt;    "jquery.ui.js"&lt;br /&gt;]).execute(function(onjQueryAndUILoaded, initialTime){&lt;br /&gt;    // execute is always performed&lt;br /&gt;    // after everything has been loaded&lt;br /&gt;    onjQueryAndUILoaded(jQuery, new Date - initialTime);&lt;br /&gt;}, [&lt;br /&gt;    // we can optionally pass one or more arguments&lt;br /&gt;    function($, elaspedTime){&lt;br /&gt;        // let's understand how much it took&lt;br /&gt;        alert(elaspedTime);&lt;br /&gt;    },&lt;br /&gt;    new Date&lt;br /&gt;]);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Understanding extend Method: Fast Bridge&lt;/h3&gt;&lt;br /&gt;Every time we execute a function inside an Elsewhere instance, we are de-compiling and injecting it inside another document. This operation is not that expensive but if we need to perform some task in that scope frequently, we could consider to extend an Elsewhere instance via its own method, creating a sort of fast bridge between two or more than two different worlds.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// empty sandbox&lt;br /&gt;var sb = new Elsewhere()&lt;br /&gt;    // extend returns the instance itself&lt;br /&gt;    .extend(&lt;br /&gt;    {&lt;br /&gt;        extendObject:function(){&lt;br /&gt;            var toString = Object.prototype.toString;&lt;br /&gt;&lt;br /&gt;            // note, this Object is not the main one&lt;br /&gt;            // but the one from this sandbox (main not affected)&lt;br /&gt;            Object.prototype.type = function(){&lt;br /&gt;                var s = toString.call(this);&lt;br /&gt;                return s.substr(8, s.length - 9);&lt;br /&gt;            };&lt;br /&gt;            &lt;br /&gt;            // avoid future modification&lt;br /&gt;            window.extendObject = function(){};&lt;br /&gt;        },&lt;br /&gt;        createObject:function(o){&lt;br /&gt;            // create an Elsewhere Object&lt;br /&gt;            return new Object(o);&lt;br /&gt;        },&lt;br /&gt;&lt;br /&gt;        // if an extend key is a global variable&lt;br /&gt;        // different from undefined&lt;br /&gt;        // this will simply be the variable from &lt;br /&gt;        // this sandbox&lt;br /&gt;        Object:1,&lt;br /&gt;&lt;br /&gt;        // if the value is not a function&lt;br /&gt;        // it will simply be saved as is&lt;br /&gt;        cool:true&lt;br /&gt;    }&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;// extend Elsewhere Object.prototype&lt;br /&gt;sb.extendObject();&lt;br /&gt;&lt;br /&gt;// test it&lt;br /&gt;var o = sb.createObject("test");&lt;br /&gt;alert(o.type());    // String&lt;br /&gt;&lt;br /&gt;// o is not instanceof this main page Object&lt;br /&gt;alert(o instanceof Object); // false&lt;br /&gt;&lt;br /&gt;// but it could be used as if was&lt;br /&gt;// an Object&lt;br /&gt;alert(o instanceof sb.Object); // true&lt;br /&gt;&lt;br /&gt;alert(sb.cool); // true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;As Summary&lt;/h3&gt;&lt;br /&gt;Elsewhere can open hundreds of possibilities without bringing nothing new, except that browsers are starting to implement different threads for each sandbox (tab, or window) and I expect this library will bring an even more simple way to implement web workers. Right now main points are conflicts resolution, when libraries are able to deal from a sandbox, new JSONP interaction ways, multiple native constructor prototype definitions via one or more Elsewhere instances, just a simple way to load external scripts or ... well, whatever else our imagination could create with such tiny, cross-browser, library. Have fun with sandboxes 8).&lt;br /&gt;&lt;br /&gt;The script? Via post title or &lt;a href="http://www.devpro.it/javascript_id_198.html"&gt;here, in devpro.it&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-5529992178695691216?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="related" href="http://www.devpro.it/javascript_id_198.html" title="Elsewhere - Sandboxes Have Never Been That Easy" /><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/5529992178695691216/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=5529992178695691216" title="13 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/5529992178695691216" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/5529992178695691216" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/1rsEMoUefbc/elsewhere-sandboxes-have-never-been.html" title="Elsewhere - Sandboxes Have Never Been That Easy" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">13</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/07/elsewhere-sandboxes-have-never-been.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-679773132323075010</id><published>2009-07-10T20:19:00.003+02:00</published><updated>2009-07-10T20:33:18.952+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="trimLeft" /><category scheme="http://www.blogger.com/atom/ns#" term="vice-versa" /><category scheme="http://www.blogger.com/atom/ns#" term="Date" /><category scheme="http://www.blogger.com/atom/ns#" term="ECMAScript 5" /><category scheme="http://www.blogger.com/atom/ns#" term="trim" /><category scheme="http://www.blogger.com/atom/ns#" term="ISO" /><category scheme="http://www.blogger.com/atom/ns#" term="trimRight" /><category scheme="http://www.blogger.com/atom/ns#" term="String" /><title type="text">ECMAScript 5 Full Specs String trim, trimLeft, and trimRight</title><content type="html">During last evenings I have updated a little bit my &lt;a href="http://code.google.com/p/vice-versa/"&gt;vice-versa project&lt;/a&gt;.&lt;br /&gt;Since vice-versa aim is to bring in every browser what is possible to implement and, in most of the cases, already defined as standard (from W3 or MSDN when it is worthy) I decided to get rid of the &lt;a href="http://flesler.blogspot.com/2008/11/fast-trim-function-for-javascript.html"&gt;Ariel Flesler fast trim proposal&lt;/a&gt; to introduce my lightweight full specs String.prototype.trim, trimLeft, and trimRight.&lt;br /&gt;For full specs I mean that &lt;a href="http://vice-versa.googlecode.com/svn/trunk/src/String.js"&gt;vice-versa String.prototype.trim&lt;/a&gt; replace exactly same characters replaced by native Firefox 3.5 implementation, rather than only characters which code is less than 33 as is for Ariel proposal.&lt;br /&gt;&lt;br /&gt;The good part of vice-versa ( to be honest I cannot find bad parts so far ;) ) is that every single file is stand-alone, so if you do not like benefits the entire "&lt;em&gt;lib&lt;/em&gt;" could bring, you can always adopt only one of its files, for example the String one, the Array one, or the &lt;a href="http://vice-versa.googlecode.com/svn/trunk/src/Date.js"&gt;last full specs ECMAScript 5 Date constructor&lt;/a&gt;, compatible with ISO strings, new Date("2009-07-10") and with a complete toISOString method for each created Date instance (of course even if replaced, new Date will produce instances of Date and their constructor will be Date itself).&lt;br /&gt;&lt;br /&gt;If you want to give vice-versa minified a try, a little monster which size is about 5Kb gzipped, please &lt;a href="http://vice-versa.googlecode.com/files/vice-versa.0.1.4b.min.js"&gt;do not hesitate to download it&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Have fun with future standards and few MSDN standard coolness for every browser ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-679773132323075010?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/679773132323075010/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=679773132323075010" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/679773132323075010" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/679773132323075010" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/pj2IUZNoq9Y/ecmascript-5-full-specs-string-trim.html" title="ECMAScript 5 Full Specs String trim, trimLeft, and trimRight" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/07/ecmascript-5-full-specs-string-trim.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-5649179013524423245</id><published>2009-07-10T01:12:00.001+02:00</published><updated>2009-07-10T01:12:54.233+02:00</updated><title type="text">Frameworks: To Choose Or Not To Choose</title><content type="html">Few days ago the BBC announced the release of their framework called Glow.&lt;br /&gt;John Resig commented this event in a "&lt;em&gt;logical and reasonable way&lt;/em&gt;" but instantly different developers reacted over his thoughts.&lt;br /&gt;What John says, in few words, is that BBC developers used jQuery before and they were partially happy with it.&lt;br /&gt;Rather than help jQuery community to grow up, opening tickets, adding patches, or forking the library itself improving it adding Safari 1.3 support, a 0% market share browser that in my opinion is used only inside BBC labs and nowhere else, they decided to spend about 2 years to create a library that apparently does not bring anything new, and which is even more supported by some obsolete or deprecated browser, rather than latest one (Chrome 1 or 2, Opera 10, or Firefox 3.5). This post is about what I think after almost 10 years of Web development experience, where I have used both frameworks and I wrote some for internal purpose. Cases are different for each situation, requirements are different as well as different could be time to create or complete a project.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;About Library Browsers Support&lt;/h3&gt;&lt;br /&gt;Dear net surfers, there is nothing to do, if you need internet, if your business is partially based on internet, if you want everything internet has to offer, &lt;strong&gt;you must be updated&lt;/strong&gt;! That's the story, and this is that simple.&lt;br /&gt;There is not a single valid excuse to be stuck in the past, and if some application in your company works only in IE6, first of all you should consider to upgrade that application, &lt;strong&gt;it's deprecated&lt;/strong&gt;, secondly you should consider alternatives at least for new Web services, that in the best case scenario will suggest you to upgrade while in the worst one will simply do NOT work and you, minority, will just miss that train!&lt;br /&gt;&lt;br /&gt;As everybody knows technologies quickly evolves and if you walk down the street with a Walkman rather than an iPod like device, you are mentally 80 years old, retired, and you are missing infinity possibilities, starting from more than an album and hours of music.&lt;br /&gt;&lt;br /&gt;Internet, the Web, the Web business, and everything around it, is drastically changing day after day.&lt;br /&gt;Reasons are different, starting from an initial and general misunderstanding about same Web standards and related logics, goals, and behaviors, ending with a revolution that thanks to new technologies, programming languages, and companies, where Google is one of the most important leaders, are acting on daily basis.&lt;br /&gt;&lt;br /&gt;In few words: are you a net surfer? Do you need internet? You are probably already upgraded, thanks to be patience and to read this post 'till the end.&lt;br /&gt;&lt;br /&gt;Are you someone that does NOT know internet, what it has to offer, does not need it for your business, and surfs the Web few minutes per month?&lt;br /&gt;&lt;strong&gt;Do not complain&lt;/strong&gt; then if the rest of the world that needs internet is moving on in the meanwhile, thank you!&lt;br /&gt;&lt;br /&gt;Are you a company that understood only recently the power of the web? If you do not upgrade your browser your business will be decades behind others!&lt;br /&gt;&lt;br /&gt;Is IE6 there because of "&lt;em&gt;security bla bla bla&lt;/em&gt;"? IE6 is one of the most bugged and vulnerable browsers in the history, fire your system administrator and move on with the rest of the world!&lt;br /&gt;&lt;br /&gt;All this effort is just to let you understand that modern web libraries are doing their best to be as much compatible as possible.&lt;br /&gt;Unfortunately, some &lt;u&gt;old browser cannot physically solve "nowadays Web problems"&lt;/u&gt; because these browsers have been programmed when internet was nothing more than a "advertisement coupon", with flashing images, providing zero services.&lt;br /&gt;&lt;br /&gt;Just consider that an iPhone or a G1, mobile devices, integrate a better browser than IE6 or Safari 1.3 ... is it time to move forward? IE8 is there, as Firefox, Chrome, Safari and Opera are. You have choices, and mainly for free, to avoid to collapse with deprecated services and applications.&lt;br /&gt;&lt;br /&gt;So, are you spending money for a Jurassic business, internet time speaking? If yes, why are you wasting money with a browser such Safari 1.3, 98% useless for every recent website, or IE6, forced to be somehow compatible but for its own limits obviously deprecated for modern businesses and applications?&lt;br /&gt;&lt;br /&gt;As summary, I do not understand why on earth BBC needs to support people that do not use internet. It could make sense to still support IE6, right now below IE8, market share speaking, but unfortunately still there thanks to people ignorance. But a browser that could be compared with Internet Explorer for Mac, abandoned by Microsoft itself years ago, cannot be a good excuse to avoid libraries ... I simply cannot believe this reason and I would like to have real stats about Safari 1.3 usage in their website.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;About Choosing Libraries Or Frameworks&lt;/h3&gt;&lt;br /&gt;There are hundreds of valid choices out there but this case is mainly about the decision to avoid jQuery.&lt;br /&gt;A good library as jQuery is, if I am not wrong the most used one right now and recently adopted in Wikipedia pages as well, has basically these pro:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;widely cross-browser supported, more market share than Glow or other home made libraries&lt;/li&gt;&lt;br /&gt;&lt;li&gt;day after day improvements, bug fixes, speed ups, thanks to an active community, a tickets system and again, thanks to its wide adoption from biggest to smallest website, which can only hep to improve jQuery stability and/or features&lt;/li&gt;&lt;br /&gt;&lt;li&gt;constant cross-browser tests, which aim is to guarantee stability and functionality over any kind of customer, client, administrator, or simply net surfer&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;These are not jQuery specific features, these are simply the reason developers prefer to use a well known library rather than an home made one.&lt;br /&gt;Less effort, most of what we need is there, and jQuery is truly reach about plug-ins, so what is not there has been probably already implemented. Charts? Timeline stuff? Widgets? Fields helpers? Almost everything, and it simply works thanks to the core library and its stability, jQuery again.&lt;br /&gt;Just to be honest, I do not even use jQuery except when I need it for compatibility or time reasons, so please do not get me wrong, I am not a fanatic, I read Ext JS, dojo, YUI, and other libraries authors or mailing lists as well so this is just an impartial point of view about libraries and nothing else but, there is always a but, I can understand as well the other point of view ...&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;About Creating Your Own Library&lt;/h3&gt;&lt;br /&gt;If we understand the reason a library or a framework is a good choice, whatever programming language we are talking about, even if latter one is created via JavaScript, the &lt;u&gt;most problematic programming language ever&lt;/u&gt; due to its intrinsic unstable or different nature (not just one virtual machine but lots of different interpreters, few strictly standard behaviors, thousands of browsers implementation bugs or standards misunderstanding, zero compilation, etc etc) there could be an absolutely valid reason to decide to create our own libraries.&lt;br /&gt;First of all, if we do not want to be "&lt;em&gt;monkeys&lt;/em&gt;" but developers, the only way we have to deeply learn a programming language and its problems is to use it as much as possible, without stopping a single day to learn more about it.&lt;br /&gt;If a library/framework does magically everything and we are not curious enough to understand how this library is solving or implementing our daily problems or features, we have probably chose the wrong job, unless we are not designers with different goals, where a library is "&lt;em&gt;just what we were looking for&lt;/em&gt;" to quickly solve "that problem" which was not Photoshop related.&lt;br /&gt;Sometimes, we could be simply not interested about the language itself, thanks to frameworks able to translate some "serious language" a la Java or C# into the blamed one: JavaScript (and to be honest I can't wait to laugh about some JavaScript related problem not considered by that framework, who you gonna call: Ghost Busters?!)&lt;br /&gt;Another important fact to consider is &lt;strong&gt;the time&lt;/strong&gt;, never enough in this "&lt;em&gt;everybody agile&lt;/em&gt;" web era where if at least the business client core functionality and its tests are delegated to someone else, we are half way through our application goals.&lt;br /&gt;But how different are things if we are plenty of time to develop our own library?&lt;ul&gt;&lt;br /&gt;&lt;li&gt;we are &lt;strong&gt;not&lt;/strong&gt; necessarily &lt;strong&gt;reinventing the wheel&lt;/strong&gt;, if we are skilled enough, and we have studied problems, features, and adopted solutions, we could simply create something new or just &lt;em&gt;perfect&lt;/em&gt; for what we need (as example, the dollar function "is prototype stuff", what jQuery did with it was simply different, but I am sure John will agree about this innovation or "just what we need" point)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;we will have &lt;strong&gt;full control over releases and source code&lt;/strong&gt;, being able to solve problems in a bit and without dependencies over third parts libraries. We all know that even if have skills to quickly change a library core feature, this library next release could probably mess up our internal patch, or vice versa, and sometimes our case is so particular or simply impossible to reproduce outside our business box, that a ticket could not make sense at all. I personally changed some library core function, or overwritten some core method, and simply because of problems and situations impossible to reproduce into the ticket system. The reason is simple: when the application is complex enough, and it is an internal one (admin areas anybody?), we cannot spend a day to create a ticket which emulates somehow our specific problem. Got the point?&lt;/li&gt;&lt;br /&gt;&lt;li&gt;the final silly point: we are developers, for code sake, and a typical stereotype is that we are all better than everybody else. In few words, if we think it, knowing what others are doing about same thoughts, we are thinking "&lt;em&gt;better than others&lt;/em&gt;", and if we are not shy to write a lot of code and test it, because we have time, why on earth we should depend again on third parts libraries?&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;As Summary&lt;/h3&gt;&lt;br /&gt;There is not an absolute point about these kind of choices, except one: &lt;strong&gt;flexibility&lt;/strong&gt;. I do appreciate the fact BBC team at least tried jQuery library before they chose to create their own one. The point about death browsers is an excuse, IMHO, they should have been more decided about their points because if that was the reason, I do not get it at all and people talking about public money would be absolutely right. On the other hand, latest points about proprietary libraries advantages could make BBC site less problemtic, for their supported browsers, considering they know what they are doing, they had even too much time to develop 300Kb of core library comment included ( I wrote 3 times of code in one month over another library and nothing was redundant ... ), and they are (ta da ta da!!!) BBC, good to see their source code (lovely comments, not everything lovely in the code though but this is another story)&lt;br /&gt;&lt;br /&gt;This post is just my humble opinion about a subject extremely common in this sector and interesting as well.&lt;br /&gt;I am just a developer with passion for code, curiosity about ASM, C knowledge, a "JavaScript Ninja" currently technical editor of an imminent related book, with PHP Zend Engineer certifications, few Java related experiences, and daily C# exposure. In few words, I have collaborated with different companies and created internal libraries or used third parts libraries. Please consider my experience so far before you'll blame me for this post, thanks :D&lt;br /&gt;&lt;br /&gt;P.S. I promise, I'll add every related link asap, right now my temporary Internet connection is running out of bytes!!!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-5649179013524423245?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/5649179013524423245/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=5649179013524423245" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/5649179013524423245" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/5649179013524423245" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/StvKe3glXy0/frameworks-to-choose-or-not-to-choose.html" title="Frameworks: To Choose Or Not To Choose" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/07/frameworks-to-choose-or-not-to-choose.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-3759828569219309246</id><published>2009-07-05T02:51:00.003+02:00</published><updated>2009-07-05T02:56:27.880+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Batch" /><category scheme="http://www.blogger.com/atom/ns#" term="YUI" /><category scheme="http://www.blogger.com/atom/ns#" term="CSS" /><category scheme="http://www.blogger.com/atom/ns#" term="JavaScirpt" /><category scheme="http://www.blogger.com/atom/ns#" term="compressor" /><title type="text">YUI Compressor Meets The Batch Scripting</title><content type="html">Mainly to work, also to investigate some good old DOS feature, I created a batch file able to make YUI Compressor more portable and easy for every Windows based client/server developer.&lt;br /&gt;I wrote the story, and I described each file, plus I added a workable Zip with everything you need to understand what I have created and use it, starting with a double click into a projects/vice-versa.bat file which aim is to create from a list of files a unique YUI Compressed one.&lt;br /&gt;&lt;a href="http://www.3site.eu/yuibompressor/"&gt;Here is the link&lt;/a&gt;, the rest is up to you (comments, questions, suggestions, etc)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-3759828569219309246?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="related" href="http://www.3site.eu/yuibompressor/" title="YUI Compressor Meets The Batch Scripting" /><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/3759828569219309246/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=3759828569219309246" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/3759828569219309246" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/3759828569219309246" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/V4-m7eHUF20/yui-compressor-meets-batch-scripting.html" title="YUI Compressor Meets The Batch Scripting" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/07/yui-compressor-meets-batch-scripting.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-8981408583511017108</id><published>2009-07-04T13:21:00.008+02:00</published><updated>2009-07-04T14:39:00.268+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bing" /><category scheme="http://www.blogger.com/atom/ns#" term="Roundtable" /><category scheme="http://www.blogger.com/atom/ns#" term="impression" /><title type="text">UK Bing Roundtable - Just My Opinion</title><content type="html">It is probably too late and I did not check other guys blogs, but I would like to bring here my impressions about this Bing event I have been invited few days ago.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;How Did It Start&lt;/h3&gt;&lt;br /&gt;&lt;blockquote&gt;Hi Andrea,&lt;br /&gt;I'm writing on behalf of Microsoft to invite you to a discussion about Bing, the new search engine that recently launched in beta in the UK.&lt;br /&gt;&lt;br /&gt;...&lt;/blockquote&gt;&lt;br /&gt;Colin Mercer, a member of Microsoft &lt;em&gt;Life Without Walls&lt;/em&gt; initiative group, is a truly nice guy. Spontaneous, friendly, exactly that kind of guy that could let a group of foreigners feel comfortable since first meet up minutes. Being glad to have been invited without asking, and without being a Microsoft fun as well, of course I was there: to understand what this initiative was about and why they called me, raising my doubts from this high geek technical blog.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Bing Round Table, The Good Part&lt;/h3&gt;&lt;br /&gt;To be honest, I am not going to be that nice about this event, but I have to admit that seeing Microsoft trying to be closer than before with people that make Web live, any topic blogger in this case, was a nice surprise. The organization, the choose place, and the catering was excellent, even if there were only about 10 guests and there was no time to eat and drink. It is a good start point from a company famous to be closed for its selling purpose only. Good Stuff, please keep doing it, it can only brings benefits from different points of view.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Special Moronic Guests, That Is What We Are&lt;/h3&gt;&lt;br /&gt;The presentation started with a lovely woman and a sort of jingle: "&lt;em&gt;Bing&lt;/em&gt;"! OK, that was to make us comfortable, that was to have a quick laugh, that was to break the ice, that was ... only the begin!&lt;br /&gt;The entire presentation showed us stats, those stats were retrieved from God Knows which tool bar present only in Internet Explorer, and those stats, even if from IE world, put Microsoft search engines in third position, I can't imagine what could come from Mozilla or Google, if they present stats based on their own products ... I guess Bing would not even exists ...&lt;br /&gt;Since those stats were not that pro-bing, they stopped into a slide with classical promises a la "&lt;em&gt;it's simple, it's friendly, it's new, it's brand, it's something you should use, it makes your life better&lt;/em&gt;" ... no comment.&lt;br /&gt;Fortunately, some guy started instantly to ask what was new, what was interesting, what was the missing piece that other well known search engines do not have ... and every question had behind a though like: why are we here and what are you showing us? We are not dummies and we know what we want, what other offer, and what we are looking for.&lt;br /&gt;Were we interested about TV ad like presentation? &lt;strong&gt;NO&lt;/strong&gt;&lt;br /&gt;Were we interested about promises other search engines maintain since ages? &lt;strong&gt;NO&lt;/strong&gt;&lt;br /&gt;Were we interested about U.S.A. verion, being in London, where Bing is still beta and smells like Live from miles without bringing a single new feature and positioning bing itself in the second place when you search for bing in the uk version? &lt;strong&gt;NO&lt;/strong&gt;&lt;br /&gt;So what were they showing us? Did they think we do not know what is a search engine? &lt;strong&gt;Probably&lt;/strong&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Missed Expectations&lt;/h3&gt;&lt;br /&gt;At least that what I think,everybody was looking for that genius thing that nobody else have ... it did not happen! Apparently, the most innovative thing is the live video preview for video results ... OK, I want to be honest, I think everybody over 18 has seen some xxx search engine and everybody knows that a quick preview in a video link is not a Bing idea ... isn't it?&lt;br /&gt;The second most important innovation is a vertical focused lateral bar, something that simply remove spaces fr mobile devices, something useful because with that kind of layout and images behind white links people could even not notice top links so here they are with an innovative lateral menu ... is this wow?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Bing UK, I Want Developers Name!&lt;/h3&gt;&lt;br /&gt;First of all, for a company that sell enterprise software a la Visual Studio Team System, I wonder how it can be possible that whatever country version is different from every other ... merge projects and use one big development team? Naaaaaaaaa, they prefer to delegate search engine development in each country ... what a waist of money! The UK version is a new graphical version of the Live.co.uk search engine, same weird results (Bing itself in second position after a link called News about Bing ...), not a single lateral bar, nothing useful in the home page ... and about this, &lt;strong&gt;110Kb&lt;/strong&gt; of home page because of course if a user needs to search something he has to wait the castle, the building, the big sized image in home page. Moreover, with &lt;strong&gt;13 inline JavaScript files&lt;/strong&gt;, when you chose a different search type switching from Web to Image, &lt;strong&gt;the entre page is reloaded and the only difference is the form action&lt;/strong&gt;, using /images/ rather than the main path ... I mean: &lt;strong&gt;Are You Serious?&lt;/strong&gt;&lt;br /&gt;Design wise, as I said in some other post I am partially color blind. I perfectly recognize red and green, but slight gradients make my life truly difficult.&lt;br /&gt;Google, in its simplicity, studied a lot color contrasts to make &lt;strong&gt;everything clear&lt;/strong&gt;, now try to read the disclaimer, or links bottom right ... oh really? You did not even know there were links there? &lt;strong&gt;I am not a designer&lt;/strong&gt;, but you do not need a PHD to understand that &lt;strong&gt;bright text over a bit brighter background does not make sense&lt;/strong&gt; ... now put white text over images loads of details ... and now tell me how long you spent to read that text, and how much all these problems do not exists in both Yahoo and Google. Is it all about design? Does it make sense to create a 100Kb home page just to add noise and confusion? Did they truly need 13 inline JavaScript for a page that has no functionality rather than a field? &lt;strong&gt;Where is the simplicity they are talking about?&lt;/strong&gt;&lt;br /&gt;Google, 25Kb, you write, you press enter, &lt;strong&gt;that's it&lt;/strong&gt;, that's why they are the number one search engine ... no confusion, not a single waist of time or bandwidth, optimized for mobile devices and even if Microsoft has more than one HTC device, they do not care ... try to surf Bing with iPhone or Android ... are we still in 2000 or in the netbook/small screen devices era? A splash in the past, and still nothing new!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Bing U.S.A. You Click Rather Than Scroll!&lt;/h3&gt;&lt;br /&gt;Again, I did not get this "feature", the vertical oriented menu on the left suppose to make everything simple &lt;em&gt;because in Gogle you have to scroll&lt;/em&gt; ... &lt;strong&gt;What?&lt;/strong&gt;&lt;br /&gt;The scrolling operation with a mouse is extremely natural and it can be performed everywhere in the page while it is still natural with mobile devices where with a finger or a dedicated button you just ... scroll! The search, point, and click is a boring, slow, tedious, operation, even more difficult with mobile devices and whatever "finger-pad" panel we all have in our mobile devices. In few words, in UK Bing presentation they showed us how simple is to find Washington map ... you search for Washington, the engine is so clever to understand that you are looking for a city ( again, moronic stuff, we all know that this is the abc for a top ten search engine ) and if you click Map in the left side menu, you will find the map. In Google, you have to scroll ( weird, I always found maps in the top of the page ) to find information, so they organized everything, with a response page which average is again about 70Kb VS 30 to 35 for Google, where in the latter one you can find everything you need in one page, quick, simple, that is simple!&lt;br /&gt;I do not want to comment the fact they proposed U.S.A. related searches, and non UK images in the home page for the UK Bing version ...&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;There Will Be Time For Technical Question?&lt;/h3&gt;&lt;br /&gt;After any sort of question and hundreds of good points about missed interesting news for this new Microsoft search engine, I simply called time to ask technical question. THey said yes but thre was no time, and you know what? I got time blowing out loudly and quickly my points producing non-sense sentences cause I lost number of things to ask or say ... but one thing I will never forget: I asked about 13 inline scripts and the reason if in the UK version I click images I have to reload the page just to change a form target ... the answer was: I do not know what you are talking about ... OK, probably misunderstanding, probably not DB related, but at the end of the day, the only though in my mind was this one: &lt;em&gt;Why on earth they called me? Did they think I was a web troll? Did they think I was a teenager with a lot of time to waist behind the PC? Did they ever consider me as a 10 years experienced web developer with deep JavaScript knowledge, server side certifications, and studies that not a single young Phd person have unless he/she has not my same passion?&lt;/em&gt;&lt;br /&gt;Disappointed, partially humiliated, and still load of doubts about how the presentation supposed to be and the reason they called us.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Is Everything That Bad?&lt;/h3&gt;One thing I truly appreciated, which does not come from this meeting, is the Bing API, in my opinion well done and flexible enough to let us create interesting applications or web gadgets. If you'll stay tuned, I am planning to create a bookmarkable script that will make searches nice, simple, and friendly, exactly how Bing should, in Microsoft mind, be.&lt;br /&gt;&lt;br /&gt;Finally, this post is only my impression, my opinions, and nothing else. I may have misunderstood a lot of words/questions, specially after a couple of fresh beers, but I still wonder why I was there ... and if I would like to be there again. Let's see how things will be.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Post Scriptum&lt;/h3&gt;All my opinions come from 30 minutes analysis in place, during the meeting, I've never had time these days to investigate the search engine itself so I may have missed something ... again, take carefully what I said about Bing, thanks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-8981408583511017108?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/8981408583511017108/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=8981408583511017108" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/8981408583511017108" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/8981408583511017108" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/PkvPiamqtM8/uk-bing-roundtable-just-my-opinion.html" title="UK Bing Roundtable - Just My Opinion" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/07/uk-bing-roundtable-just-my-opinion.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-2703792690901564925</id><published>2009-07-04T12:47:00.006+02:00</published><updated>2009-07-06T10:12:55.166+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="8601" /><category scheme="http://www.blogger.com/atom/ns#" term="Date" /><category scheme="http://www.blogger.com/atom/ns#" term="ECMAScript 5" /><category scheme="http://www.blogger.com/atom/ns#" term="ISO" /><category scheme="http://www.blogger.com/atom/ns#" term="toISOString" /><title type="text">ECMAScript ISO Date For Every Browser</title><content type="html">One most than welcome new entry of ECMAScript 5 is the Date.prototype.toISOString function and ability for Date constructor to accept an ISO String and to generate a Date instance.&lt;br /&gt;This feature will make JSON Date instances import/export extremely fast and simple, but why should we wait ES5 release when we can have both features now?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Full Specs ISO 8601 Parser Plus Unobtrusive toISOString Method&lt;/h3&gt;&lt;br /&gt;We all do not like that much to extend native JavaScript constructors, so here I am with a proposal that will not touch the Date prototype:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;if(!Date.ISO)(function(){&amp;quot;use strict&amp;quot;;&lt;br /&gt;/** ES5 ISO Date Parser Plus toISOString Method&lt;br /&gt; * @author          Andrea Giammarchi&lt;br /&gt; * @blog            WebReflection&lt;br /&gt; * @version         2009-07-04T11:36:25.123Z&lt;br /&gt; * @compatibility   Chrome, Firefox, IE 5+, Opera, Safari, WebKit, Others&lt;br /&gt; */&lt;br /&gt;function ISO(s){&lt;br /&gt;    var m = /^(\d{4})(-(\d{2})(-(\d{2})(T(\d{2}):(\d{2})(:(\d{2})(\.(\d+))?)?(Z|((\+|-)(\d{2}):(\d{2}))))?)?)?$/.exec(s);&lt;br /&gt;    if(m === null)&lt;br /&gt;        throw new Error(&amp;quot;Invalid ISO String&amp;quot;);&lt;br /&gt;    var d = new Date;&lt;br /&gt;    d.setUTCFullYear(+m[1]);&lt;br /&gt;    d.setUTCMonth(m[3] ? (m[3] &amp;gt;&amp;gt; 0) - 1 : 0);&lt;br /&gt;    d.setUTCDate(m[5] &amp;gt;&amp;gt; 0);&lt;br /&gt;    d.setUTCHours(m[7] &amp;gt;&amp;gt; 0);&lt;br /&gt;    d.setUTCMinutes(m[8] &amp;gt;&amp;gt; 0);&lt;br /&gt;    d.setUTCSeconds(m[10] &amp;gt;&amp;gt; 0);&lt;br /&gt;    d.setUTCMilliseconds(m[12] &amp;gt;&amp;gt; 0);&lt;br /&gt;    if(m[13] &amp;amp;&amp;amp; m[13] !== &amp;quot;Z&amp;quot;){&lt;br /&gt;        var h = m[16] &amp;gt;&amp;gt; 0,&lt;br /&gt;            i = m[17] &amp;gt;&amp;gt; 0,&lt;br /&gt;            s = m[15] === &amp;quot;+&amp;quot;&lt;br /&gt;        ;&lt;br /&gt;        d.setUTCHours((m[7] &amp;gt;&amp;gt; 0) + s ? -h : h);&lt;br /&gt;        d.setUTCMinutes((m[8] &amp;gt;&amp;gt; 0) + s ? -i : i);&lt;br /&gt;    };&lt;br /&gt;    return toISOString(d);&lt;br /&gt;};&lt;br /&gt;var toISOString = Date.prototype.toISOString ?&lt;br /&gt;    function(d){return d}:&lt;br /&gt;    (function(){&lt;br /&gt;        function t(i){return i&amp;lt;10?&amp;quot;0&amp;quot;+i:i};&lt;br /&gt;        function h(i){return i.length&amp;lt;2?&amp;quot;00&amp;quot;+i:i.length&amp;lt;3?&amp;quot;0&amp;quot;+i:3&amp;lt;i.length?Math.round(i/Math.pow(10,i.length-3)):i};&lt;br /&gt;        function toISOString(){&lt;br /&gt;            return &amp;quot;&amp;quot;.concat(&lt;br /&gt;                this.getUTCFullYear(), &amp;quot;-&amp;quot;,&lt;br /&gt;                t(this.getUTCMonth() + 1), &amp;quot;-&amp;quot;,&lt;br /&gt;                t(this.getUTCDate()), &amp;quot;T&amp;quot;,&lt;br /&gt;                t(this.getUTCHours()), &amp;quot;:&amp;quot;,&lt;br /&gt;                t(this.getUTCMinutes()), &amp;quot;:&amp;quot;,&lt;br /&gt;                t(this.getUTCSeconds()), &amp;quot;.&amp;quot;,&lt;br /&gt;                h(&amp;quot;&amp;quot; + this.getUTCMilliseconds()), &amp;quot;Z&amp;quot;&lt;br /&gt;            );&lt;br /&gt;        };&lt;br /&gt;        return function(d){&lt;br /&gt;            d.toISOString = toISOString;&lt;br /&gt;            return d;&lt;br /&gt;        }&lt;br /&gt;    })()&lt;br /&gt;;&lt;br /&gt;Date.ISO = ISO;&lt;br /&gt;})();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The public static ISO Date method accepts a valid ISO 8601 String compatible with &lt;a href="http://www.w3.org/TR/NOTE-datetime"&gt;W3 Draft&lt;/a&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;   Year:&lt;br /&gt;      YYYY (eg 1997)&lt;br /&gt;   Year and month:&lt;br /&gt;      YYYY-MM (eg 1997-07)&lt;br /&gt;   Complete date:&lt;br /&gt;      YYYY-MM-DD (eg 1997-07-16)&lt;br /&gt;   Complete date plus hours and minutes:&lt;br /&gt;      YYYY-MM-DDThh:mmTZD (eg 1997-07-16T19:20+01:00)&lt;br /&gt;   Complete date plus hours, minutes and seconds:&lt;br /&gt;      YYYY-MM-DDThh:mm:ssTZD (eg 1997-07-16T19:20:30+01:00)&lt;br /&gt;   Complete date plus hours, minutes, seconds and a decimal fraction of a second&lt;br /&gt;      YYYY-MM-DDThh:mm:ss.sTZD (eg 1997-07-16T19:20:30.45+01:00)&lt;br /&gt;&lt;br /&gt;where:&lt;br /&gt;&lt;br /&gt;     YYYY = four-digit year&lt;br /&gt;     MM   = two-digit month (01=January, etc.)&lt;br /&gt;     DD   = two-digit day of month (01 through 31)&lt;br /&gt;     hh   = two digits of hour (00 through 23) (am/pm NOT allowed)&lt;br /&gt;     mm   = two digits of minute (00 through 59)&lt;br /&gt;     ss   = two digits of second (00 through 59)&lt;br /&gt;     s    = one or more digits representing a decimal fraction of a second&lt;br /&gt;     TZD  = time zone designator (Z or +hh:mm or -hh:mm)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The only limit is about milliseconds and JavaScript Date itself, the latest parameter will be rounded if there are more than 3 digits (JS precision is up to a millisecond, no microsecond yet).&lt;br /&gt;The toISOString method is created for every browser that does not support this prototype yet but it is simply assigned and compiled once to avoid Date prototype problems and to optimize memory and performances.&lt;br /&gt;I interpreted ISO specs as Zulu default:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;var normalDate = new Date(2009, 06, 04);&lt;br /&gt;var ISODate = Date.ISO("2009-07-04");&lt;br /&gt;&lt;br /&gt;normalDate.toISOString = ISODate.toISOString;&lt;br /&gt;&lt;br /&gt;alert([ // being in UK ...&lt;br /&gt;&lt;br /&gt;    // 2009-07-03T23:00:00.000Z&lt;br /&gt;    normalDate.toISOString(),&lt;br /&gt;&lt;br /&gt;    // 2009-07-04T00:00:00.000Z&lt;br /&gt;    ISODate.toISOString()&lt;br /&gt;].join("\n"));&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Since solar time is +01 hour, if I create a Date with midnight time, the respective Zulu one (UTC) will be the day before at 23:00:00 while since ISO consider an unspecified Time Zone the Zulu one, +00:00, the created Date will be exactly the specified one but obviously if we try to get ISODate.getHours() it will be 01 and not 00, accordingly with my local settings.&lt;br /&gt;&lt;br /&gt;This is a little function/proposal that has zero dependencies, is widely compatible, and could be a standard or a must for every library/framework. Waiting for your thoughts, have a nice we 8)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-2703792690901564925?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/2703792690901564925/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=2703792690901564925" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/2703792690901564925" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/2703792690901564925" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/QzLOtxt55G4/ecmascript-iso-date-for-every-browser.html" title="ECMAScript ISO Date For Every Browser" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/07/ecmascript-iso-date-for-every-browser.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-7845581301152345566</id><published>2009-06-28T15:16:00.002+02:00</published><updated>2009-06-28T15:24:56.679+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="bing" /><title type="text">Bing Round Table - Tomorrow</title><content type="html">Tomorrow I am going to #&lt;a href="http://search.twitter.com/search?q=%23meetbing"&gt;meetbing&lt;/a&gt; to talk about &lt;a href="http://www.collegehumor.com/video:1915736"&gt;Bing&lt;/a&gt; ( :P ) and its present/future.&lt;br /&gt;The event has been better described by &lt;a href="http://www.leggetter.co.uk/2009/06/27/bing-com-round-table.html"&gt;Phil Leggetter&lt;/a&gt; and as He did, I would like to know if there is any tech question you would like me to bring there.&lt;br /&gt;&lt;br /&gt;So far, I kinda like what &lt;a href="http://www.bing.com/developers/"&gt;Bing API&lt;/a&gt; offers, and I am planning to use it soon, but my only concern is about requests limits over a single IP.&lt;br /&gt;Thinking about firewalled/natted/DHCPped infrastructure, 7 different people could not use a generic Bing gadget in the same moment ... anything else?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-7845581301152345566?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/7845581301152345566/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=7845581301152345566" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/7845581301152345566" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/7845581301152345566" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/QCkeuy0lbXc/bing-round-table-tomorrow.html" title="Bing Round Table - Tomorrow" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/06/bing-round-table-tomorrow.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-6537555973512167994</id><published>2009-06-24T21:55:00.006+02:00</published><updated>2009-06-24T23:15:37.556+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="arguments" /><category scheme="http://www.blogger.com/atom/ns#" term="ECMAScript 5" /><category scheme="http://www.blogger.com/atom/ns#" term="callee" /><title type="text">ES5 arguments and callee, I was wrong!</title><content type="html">JavaScript is not JavaScript, I am not crazy, it is just a consideration between the language itself and what is behind it: another programming language with lower level rules and logic ... sounds silly and obvious, but please keep reading to understand what I mean.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;No Results Yet, But I've Already Lost My Battle&lt;/h3&gt;I spread comments, I wrote &lt;a href="http://webreflection.blogspot.com/2009/05/ecmascript-5-do-not-remove.html"&gt;post&lt;/a&gt; &lt;a href="http://webreflection.blogspot.com/2009/06/javascript-arguments-weridness.html"&gt;after&lt;/a&gt; &lt;a href="http://webreflection.blogspot.com/2009/06/do-not-remove-argumentscallee-part-ii.html"&gt;posts&lt;/a&gt; to defend ECMAScript 5 arguments.callee decision with "use strict", but I have to admit I have never investigate the internal behavior of callee, an arguments property which is not what we think is ...&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Discovering In Core The Callee Property&lt;/h3&gt;What I was thinking was something hilarious for a C or C++ programmer: an inherited property for a mutable instance.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// JavaScript should have a "secret" Arguments class&lt;br /&gt;// and for each function, something like this&lt;br /&gt;function Test(){};&lt;br /&gt;&lt;br /&gt;// we have declared the function Test&lt;br /&gt;// internally there should be a secret operation like this:&lt;br /&gt;&lt;br /&gt;Test._createArguments = function(args){&lt;br /&gt;    for(var i = 0; i &lt; args.length; i++)&lt;br /&gt;        this[i] = args[i];&lt;br /&gt;};&lt;br /&gt;Test._createArguments.prototype.callee = Test;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// and for each Test call, there should be&lt;br /&gt;// a secret operation like this one:&lt;br /&gt;Test._injectArguments(&lt;br /&gt;    new Test._createArguments(args);&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;// in order to retrieve Test arguments&lt;br /&gt;// variable for each call ... inheriting&lt;br /&gt;// automatically the callee property&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Apparently, except for Internet Explorer, I was so wrong.&lt;br /&gt;arguments.callee is not a pointer or a static variable retrieved instantly as &lt;code&gt;{callee:"it's a me!"}.callee&lt;/code&gt; could be, arguments, plus callee is &lt;strong&gt;a property with a "discover latency" able to make each call execution up to 100 times slower&lt;/strong&gt; than a regular function!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;We Want Perfomance? Get Rid Of Arguments And Callee Then!&lt;/h3&gt;Even with most advanced JavaScript Engines, like the V8 one used by Google Chrome Browser, arguments and arguments.callee are a big bottleneck. Test by yourself!&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;(function(){&lt;br /&gt;// Array to store execution time&lt;br /&gt;var execution = [];&lt;br /&gt;&lt;br /&gt;// named function&lt;br /&gt;function factorial(i){&lt;br /&gt;    return i &lt; 2 ? i : i * factorial(i - 1);&lt;br /&gt;};&lt;br /&gt;for(var i = 0, t = new Date; i &lt; 1000; ++i)&lt;br /&gt;    factorial(100);&lt;br /&gt;t = new Date - t;&lt;br /&gt;execution.push(&lt;br /&gt;    "Native named function: " + t&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;// named function with arguments&lt;br /&gt;function fact(i){&lt;br /&gt;    var i = arguments[0];&lt;br /&gt;    return i &lt; 2 ? i : i * fact(i - 1);&lt;br /&gt;};&lt;br /&gt;for(var i = 0, t = new Date; i &lt; 1000; ++i)&lt;br /&gt;    fact(100);&lt;br /&gt;t = new Date - t;&lt;br /&gt;execution.push(&lt;br /&gt;    "Native named with arguments: " + t&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;// arguments.callee&lt;br /&gt;fact1 = function(i){&lt;br /&gt;    return i &lt; 2 ? i : i * arguments.callee(i - 1);&lt;br /&gt;};&lt;br /&gt;for(var i = 0, t = new Date; i &lt; 1000; ++i)&lt;br /&gt;    fact1(100);&lt;br /&gt;t = new Date - t;&lt;br /&gt;execution.push(&lt;br /&gt;    "arguments.callee: " + t&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;alert(execution.join("\n"));&lt;br /&gt;})();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Impressive is the responsiveness of Internet Explorer, the browser which is "die hard" and the only one I was trying to defend about this decision, due to &lt;a href="http://thinkweb2.com/projects/prototype/named-function-expressions-demystified/"&gt;named functions misbehavior&lt;/a&gt;. IE is about 100 times slower when arguments variable is used, while Firefox 3 for example is about 50 time slower when arguments.callee is discovered. Chrome is about 4 times slower with both arguments, and callee, and the same is for Safari and Opera, impressive results. A little note about Chrome, apparently the main problem is the scope resolution, rather than arguments or callee.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;We Still Love Scripting: A Callee Proposal&lt;/h3&gt;During these tests, I can proudly say I found a way to understand in which era we are, thanks to this simple snippet:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// WebReflection knows if we are in ES5 era!&lt;br /&gt;navigator.ES5 = (function(){"use strict";try{return !arguments.callee}catch(e){return true}})();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Avoiding conflicts via global navigator object, ES5 will tell us if the browser is compatible with ECMAScript 5 "use strict"; rule or not, allowing our code to behave differently when necessary.&lt;br /&gt;It does not really matter in any case, to use my callee proposal we need to inject a callee property, as I suggested in the latest post, and for the sake of good gode, via eval:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// Another WebReflection Silly Idea&lt;br /&gt;function F/*or whatever name you prefer*/(callee){&lt;br /&gt;    return eval("(callee="+callee+")");&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Above function is able to take a &lt;strong&gt;user defined&lt;/strong&gt; function and to inject a callee property creating another defined function, a sort of operation usually performed once and never again. In few words, inside our function body we will find another variable with local scope: callee&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;(function(){&lt;br /&gt;"use strict"; // or not&lt;br /&gt;&lt;br /&gt;var execution = [];&lt;br /&gt;&lt;br /&gt;// create the function via F&lt;br /&gt;factorial = F(function(i){&lt;br /&gt;    // we got arguments, and callee&lt;br /&gt;    return i &lt; 2 ? i : i * callee(i - 1);&lt;br /&gt;});&lt;br /&gt;for(var i = 0, t = new Date; i &lt; 1000; ++i)&lt;br /&gt;    factorial(100);&lt;br /&gt;t = new Date - t;&lt;br /&gt;execution.push(&lt;br /&gt;    "WebReflection F: " + t&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;alert(execution.join("\n"));&lt;br /&gt;})();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This strategy is particularly useful for these cases:&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;    &lt;li&gt;classic configuration object, new Ext.Panel({listeners:render:F(function(Panel){&lt;br /&gt;    Panel.removeListener("render", callee);&lt;br /&gt;})})&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;classic pre-compiled function, var circle = F(Function("r,i","return !i ? r*callee(r," + Math.PI + ") : r*i"));&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;every time we would like to retrieve arguments.callee&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Last point is the one that should let us think about what we have done so far.&lt;br /&gt;If we try to execute latest benchmark, we will realize that specially with Internet Explorer, the evaluation trap works faster than arguments.callee so every time we need callee, but we do not need arguments, we should go for it.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Deeper Investigation&lt;/h3&gt;I'll keep digging inside this stuff but right now the only thing I can say is that I will try to avoid the usage of arguments.callee every single time I can because specially for the already JS speaking slow browser Internet Explorer, it is a performances killer I could not even imagine.&lt;br /&gt;&lt;br /&gt;I hope I gave you more knowledge about this problem and why ECMAScript group decided to get rid of callee, and in a possible future get rid of arguments as well. One side is pro &lt;em&gt;scriptish stuff&lt;/em&gt;, and we all love it, bot the other side is about how much this stuff could slow down Web possibilities. Stay tuned!&lt;br /&gt;&lt;br /&gt;P.S. amazing, in FF and Chrome you can set whatever property into the navigator object and rather than transform it into a string a la window.name, you can safe whatever amount of data without loosing it until you do not close that tab!!! Stay tuned for this as well, it is a new security or hack problem we could use for better purposes ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-6537555973512167994?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/6537555973512167994/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=6537555973512167994" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6537555973512167994" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6537555973512167994" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/nL8gffE5btI/es5-arguments-and-callee-i-was-wrong.html" title="ES5 arguments and callee, I was wrong!" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/06/es5-arguments-and-callee-i-was-wrong.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-7642992041841233108</id><published>2009-06-22T23:43:00.006+02:00</published><updated>2009-06-23T09:04:18.688+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="arguments" /><category scheme="http://www.blogger.com/atom/ns#" term="ECMAScript 5" /><title type="text">Do Not Remove arguments.callee - Part II</title><content type="html">Few days ago &lt;a href="http://yura.thinkweb2.com/named-function-expressions/"&gt;kangax demystified named function expressions&lt;/a&gt;, underling the importance of the read only function name property and how messy is Internet Explorer JScript engine with named function and their scope.&lt;br /&gt;&lt;br /&gt;Before that post, I wrote one about ECMAScript 5 decision to remove &lt;a href="https://developer.mozilla.org/En/Core_JavaScript_1.5_Reference/Functions_and_function_scope/arguments/callee"&gt;arguments.callee&lt;/a&gt; when "use strict"; is present (note in the link: it is not deprecated right now, it is an arguments property)&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;How These Two Things Are Related&lt;/h3&gt;While kangax post was more focused about possible leaks and unexpected functions definitions, I would like to grab more attention about what this problem will cause in tomorrow libraries and JavaScript usage. Removing arguments.callee, our code size, apparently faster in core thanks to this missed variable, will increase drastically and a big part of the beauty of JavaScript language will disappear with this callee decision.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Classic Configuration Object Problem&lt;/h3&gt;How many libraries base constructors via configuration objects?&lt;br /&gt;jQuery Ajax ?&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;$.ajax({&lt;br /&gt;    url:"page.server",&lt;br /&gt;    success:function(data){&lt;br /&gt;        if(data){&lt;br /&gt;            $.ajax({&lt;br /&gt;                url:"fallback.server",&lt;br /&gt;                success:arguments.callee&lt;br /&gt;            });&lt;br /&gt;        } else&lt;br /&gt;            alert("everything is OK");&lt;br /&gt;    }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;NO? Simple enough, but of course I could use the "long kangax procedure" to wrap that function to avoid IE problems ... and in any case, what about two Ajax calls in the same page?&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;$.ajax({&lt;br /&gt;    url:"page.server",&lt;br /&gt;    success:function success(data){&lt;br /&gt;        // whatever will be&lt;br /&gt;        // .... but don't ya think it is a bit&lt;br /&gt;        // redundant? How will be our code style,&lt;br /&gt;        // worse than an open close XML tag?&lt;br /&gt;    }&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;// second call ...&lt;br /&gt;$.ajax({&lt;br /&gt;    url:"page.server",&lt;br /&gt;    success:function success(data){&lt;br /&gt;        // which one will be the&lt;br /&gt;        // function success in&lt;br /&gt;        // Internet Explorer ???&lt;br /&gt;    }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;More comes with User Interface libraries, take ExtJS as example ...&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;new Ext.Panel({&lt;br /&gt;    renderTo:document.body,&lt;br /&gt;    listeners:{&lt;br /&gt;        render:function(Panel){&lt;br /&gt;            // do some stuff ... and ...&lt;br /&gt;            Panel.removeListener("render", arguments.callee);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Above snippets is so simple that ECMAScript 5 better decided to transform it into something like this:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;new Ext.Panel({&lt;br /&gt;    renderTo:document.body,&lt;br /&gt;    listeners:{&lt;br /&gt;        // not suitable for IE and multiple&lt;br /&gt;        // Panel creations ...&lt;br /&gt;        render:function render(Panel){&lt;br /&gt;            Panel.removeListener("render", render);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;// suitable for IE as well&lt;br /&gt;new Ext.Panel({&lt;br /&gt;    renderTo:document.body,&lt;br /&gt;    listeners:{&lt;br /&gt;        render:function(Panel){&lt;br /&gt;            var callee = Panel.initialConfig.listeners.render;&lt;br /&gt;            // note how long and boring is precedent string/operation&lt;br /&gt;&lt;br /&gt;            Panel.removeListener("render", callee);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In few words, we have to forget shortcuts to add and remove listeners for any kind of configuration object. Nice, isn't it?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Classic Pre Compiled Function Problem&lt;/h3&gt;Another problem comes with Function constructor, able to create an anonymous function (lambda) via string and a preferred solution over eval calls. A pre compiled function is something created once and executed at "native speed" for each call. Example:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// classic function&lt;br /&gt;function circle(r){&lt;br /&gt;    return r * r * Math.PI;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// pre compiled one&lt;br /&gt;var circle = Function("r", "return r * r * " + Math.PI);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The main difference between above functions is that the first one needs to discover in the scope the Math "variable" plus its PI parameters for each call, while the second one will be exactly the function:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;function anonymous(r) {&lt;br /&gt;    return r * r * 3.141592653589793;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;which is about 1.6 to 2 times faster than the other one .... cool? Perfect, now try to imagine that our pre-compiled function is more complicated and inside a closure ... how the hell do you think to retrieve the function itself?&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;(function(){&lt;br /&gt;// my library scope&lt;br /&gt;&lt;br /&gt;// this one will generate an errror&lt;br /&gt;// Function evaluates in a global scope&lt;br /&gt;var f = Function("i", "return i &lt; 2 ? i : i + f(i - 1)");&lt;br /&gt;&lt;br /&gt;// we have only two options here ...&lt;br /&gt;// the elegant one:&lt;br /&gt;var f = Function("i", "return i &lt; 2 ? i : i + arguments.callee(i - 1)");&lt;br /&gt;&lt;br /&gt;// or the horrible namespace conflicts prone one ...&lt;br /&gt;var hopefullyNoProblems = "myLib" + (""+Math.random()).slice(2);&lt;br /&gt;window[hopefullyNoProblems] =&lt;br /&gt;    Function("i", "return i &lt; 2 ? i : i + window." + hopefullyNoProblems + "(i - 1)");&lt;br /&gt;&lt;br /&gt;})();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Cool enough? That function will be extremely slower than a pre-compiled one due to the global window object which is a variable not that fast to retrieve.&lt;br /&gt;Moreover, since they decided that null or undefined should not be considered as window object, the usage of this of run-time called function is not a shortcut anymore, is it?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;As Summary&lt;/h3&gt;This is my last chance to explain the importance of arguments.callee which is NOT the reason JavaScript is less secure, it is only a pain in the ass for JS engines developers as is arguments variable itself, the magic one which apparently is going to disappear as well.&lt;br /&gt;What I do not understand, is why they do not make callee a reserved keyword and put this variable inside the function body as is for arguments and the function name.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;function itsEasy(i){&lt;br /&gt;    // itsEasy lives only here in every browser except IE&lt;br /&gt;    // arguments lives only here in every browser&lt;br /&gt;    // so it is simple to put itsEasy, arguments,&lt;br /&gt;    // but so many problems with a callee variables ?&lt;br /&gt;    return i &lt; 2 ? i : i + callee(i - 1);&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;We'll see how much we will have to change our code and how bigger will be for this non-sense decision ... JavaScript beauties should not be changed, even PHP has at least a function to retrieve the arguments array ... put a function then, whatever other solution, but please do not constrict developers to name in a completely meaningless and redundant way every single lambda. Not a single lambda based language is that fossy about it, IMHO.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-7642992041841233108?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/7642992041841233108/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=7642992041841233108" title="17 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/7642992041841233108" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/7642992041841233108" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/CtEiG3BH1pI/do-not-remove-argumentscallee-part-ii.html" title="Do Not Remove arguments.callee - Part II" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">17</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/06/do-not-remove-argumentscallee-part-ii.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-8139630978293862776</id><published>2009-06-21T13:53:00.006+02:00</published><updated>2009-06-21T15:15:36.895+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="arguments" /><title type="text">JavaScript arguments Weirdness!</title><content type="html">As you know, arguments is a "magic undeclared variable" with a local scope present in each function body. This variable is an Object, with an Array like structure.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;&lt;br /&gt;checkArgs(1, 2, 3);&lt;br /&gt;&lt;br /&gt;function checkArgs(){&lt;br /&gt;    // even if we do not declare&lt;br /&gt;    // arguments, this one will&lt;br /&gt;    // be present with a length property&lt;br /&gt;    // equal to 3 and respective&lt;br /&gt;    // 1, 2, and 3 values at index&lt;br /&gt;    // 0, 1, and 2&lt;br /&gt;    arguments.length; // 3&lt;br /&gt;    arguments[0]; // 1&lt;br /&gt;    Array.prototype.join.call(arguments,"-");&lt;br /&gt;    // will produce 1-2-3&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Nothing new so far, but I bet not everybody knew some arguments "feature" which is browser dependent or somehow re-usable.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Common "For In" Behavior&lt;/h3&gt;There is a particular behavior about arguments variable, &lt;strong&gt;it does not expose properties in a "for in" loop&lt;/strong&gt;.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;&lt;br /&gt;checkArgs(1, 2, 3);&lt;br /&gt;&lt;br /&gt;function checkArgs(){&lt;br /&gt;    for(var key in arguments)&lt;br /&gt;        alert(key);&lt;br /&gt;    // nothing happened ...&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;How can be possible? Simple enough, 0, 1, and 2 index properties are not user defined but JavaScript core assignments. Since JavaScript nature is extremely dynamic, it is simple to define what you want to expose in a loop, so far user defined properties or methods, and what should not be iterated in a "for in", something we will be able to manually introduce in next JavaScript release.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Initial Weirdness&lt;/h3&gt;&lt;br /&gt;Funny enough, even if we reassign indexed properties, these will not be exposes in the loop, but if we set an extra index or property, this one will probably be exposed.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;checkArgs(1, 2, 3);&lt;br /&gt;&lt;br /&gt;function checkArgs(){&lt;br /&gt;    for(var i = 0; i &lt; arguments.length; ++i)&lt;br /&gt;        arguments[i] = arguments[i];&lt;br /&gt;    // the extra index, manually assigned&lt;br /&gt;    arguments[3] = 4;&lt;br /&gt;    for(var key in arguments)&lt;br /&gt;        alert(key);&lt;br /&gt;        // will be 3 in FF and IE&lt;br /&gt;    // still nothing in Chrome&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;And as soon as we change the length property, this one could be exposed (FF, IE) or not (Chrome). So what we have so far?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Zero Stress for Extended Object.prototype Checks?&lt;/h3&gt;&lt;br /&gt;Since as I said arguments is always part of a function body, we could use this variable to know if some piece of code changed the Object prototype, rather than create a new object for each check.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;function someGeniusExtendedObjectPrototype(){&lt;br /&gt;    for(var k in arguments)&lt;br /&gt;        return true;&lt;br /&gt;    return false;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Unfortunately, this is not worthy, because the empty inline Object instance creation performs better than a scope resolution for an undeclared variable as arguments is.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;function someGeniusExtendedObjectPrototype(){&lt;br /&gt;    for(var k in {})return true;return false;&lt;br /&gt;};&lt;br /&gt;// that's it&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;An Instance With Not Exposed Indexes?&lt;/h3&gt;&lt;br /&gt;We could think to use arguments as a Function prototype in order to create objects ... wait a minute, NO! We could think to create a function that will directly make the magic argument public, rather than internal.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// global window scope&lt;br /&gt;// where arguments has no&lt;br /&gt;// meaning&lt;br /&gt;// NOTE: do not use with Internet Explorer&lt;br /&gt;function arguments(){&lt;br /&gt;    return arguments;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// let's test it&lt;br /&gt;var a = arguments(1, 2, 3);&lt;br /&gt;&lt;br /&gt;// loop ?&lt;br /&gt;for(var k in a)&lt;br /&gt;    alert(k); // nothing!&lt;br /&gt;&lt;br /&gt;// it "works"!&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Unfortunately, the super innovative, secure, and efficient with advanced tab isolation and recovery browser &lt;strong&gt;Internet Explorer 8 crashes like a charm&lt;/strong&gt;, so we need to rename the function into something less ambiguous for the magic JScript engine.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// use with Internet Explorer too&lt;br /&gt;function args(){&lt;br /&gt;    return arguments;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;A Magic Object Creation?&lt;/h3&gt;Using latest snippet, we could abuse about "for in" feature to create our favourite library ... maybe ...&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;function MyCoolCollection(){&lt;br /&gt;    // will be exposed in IE and FireFox&lt;br /&gt;    arguments.push = Array.prototype.push;&lt;br /&gt;    // will be exposed in FireFox&lt;br /&gt;    arguments.toString = Array.prototype.join;&lt;br /&gt;    return arguments;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;var a = MyCoolCollection(1, 2, 3);&lt;br /&gt;&lt;br /&gt;// nothing only in Chrome&lt;br /&gt;for(var k in a)&lt;br /&gt;    alert(k);&lt;br /&gt;&lt;br /&gt;// with this, IE will expose added index "3" and length&lt;br /&gt;a.push(4);&lt;br /&gt;&lt;br /&gt;alert(a); // 1,2,3,4&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Nada, nien, nothing ... arguments is destined to be arguments, damn it!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;arguments as prototype&lt;/h3&gt;Trying to discover more arguments freaking stuff, I used this magic variable as prototype:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;(function(){"use strict";&lt;br /&gt;&lt;br /&gt;// reusable in-scope constructor&lt;br /&gt;function $(){};&lt;br /&gt;&lt;br /&gt;// the magic ArgList function&lt;br /&gt;window.ArgList = function ArgList(){&lt;br /&gt;&lt;br /&gt;    // assign arguments as prototype&lt;br /&gt;    $.prototype = arguments;&lt;br /&gt;&lt;br /&gt;    // return a new magic instance&lt;br /&gt;    return new $;&lt;br /&gt;};&lt;br /&gt;})();&lt;br /&gt;&lt;br /&gt;var a = ArgList(1,2,3);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Everything seems to be OK except Internet Explorer does not expose properties until you manually discover them:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// after above snippet ...&lt;br /&gt;Array.prototype.slice.call(a);&lt;br /&gt;// ",," in Internet Explorer&lt;br /&gt;// 1,2,3 in every other browser&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Cool enough, we just discover a property and magic happens again:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;a[1];&lt;br /&gt;Array.prototype.slice.call(a);&lt;br /&gt;// ",2," in Internet Explorer&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Sometimes I forget we have to deal with a browser which logic is to bring internally even user comments:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;var f = ( /* hi scope! */ function(){ /* hi bracket! */ } );&lt;br /&gt;alert(f);&lt;br /&gt;// will be exactly:&lt;br /&gt;// ( /* hi scope! */ function(){ /* hi bracket! */ } )&lt;br /&gt;// the magic of an efficient code parser&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;As summary, to use arguments as prototype the function should be modified for IE:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;(function(){"use strict";&lt;br /&gt;function $(){};&lt;br /&gt;window.ArgList = function ArgList(){&lt;br /&gt;    $.prototype = arguments;&lt;br /&gt;    var o = new $, i = o.length;&lt;br /&gt;    while(i--)o[i]; // just access ...&lt;br /&gt;    return o;&lt;br /&gt;};&lt;br /&gt;})();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Firefox Specific Weirdness&lt;/h3&gt;arguments has some secret negative index in every Firefox (Spidermonkey) engine. For example, the index [-2] contains the length of the arguments object, but it does not perform faster than arguments.length, useless. The index [-3] contains the function itself:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;function args(){&lt;br /&gt;    alert(arguments[-3] === arguments.callee);&lt;br /&gt;    alert(arguments[-2] === arguments.length);&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In a valueOf operation, arguments[0] contains a sort of information, undefined, or "number", which could tell us if the object is going to be casted as a number:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;var o = {&lt;br /&gt;    push:[].push,&lt;br /&gt;    length:0,&lt;br /&gt;    toString:[].join,&lt;br /&gt;    valueOf:function(){&lt;br /&gt;        return arguments[0] == "number" ? this.length : this.toString();&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;o.push(1, 2, 3);&lt;br /&gt;&lt;br /&gt;alert(o);   // 1,2,3&lt;br /&gt;alert(o*1); // 3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Is That It?&lt;/h3&gt;&lt;br /&gt;I am sure every browser has some weird behavior with arguments variable so more than an inspiration for ArrayLike Objects, we cannot truly rely that much in this magic variable. What did you discover guys?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-8139630978293862776?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/8139630978293862776/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=8139630978293862776" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/8139630978293862776" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/8139630978293862776" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/vqr0J5My4FM/javascript-arguments-weridness.html" title="JavaScript arguments Weirdness!" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/06/javascript-arguments-weridness.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-8486053658357050725</id><published>2009-06-17T20:32:00.006+02:00</published><updated>2009-06-17T21:27:06.903+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Ten Grand" /><category scheme="http://www.blogger.com/atom/ns#" term="Internet Explorer" /><category scheme="http://www.blogger.com/atom/ns#" term="Microsoft" /><title type="text">The One With Microsoft Paying Users</title><content type="html">You probably do not know what's happened today at about UTC lunch time. It has been just a quick twit from &lt;a href="http://ejohn.org/"&gt;John Resig&lt;/a&gt;, that at least every follower instantly noticed the next Microsoft campaign pro Internet Explorer 8.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Fact&lt;/h3&gt;Microsoft Australia launched a sort of "&lt;em&gt;competition&lt;/em&gt;", called &lt;strong&gt;&lt;a href="http://www.microsoft.com/australia/ie8/competition/"&gt;Ten Grand&lt;/a&gt;&lt;/strong&gt;. Apparently, starting from Friday 19th, a twit will be released each N hours, creating a sort of one day investigation to discover where the price is (in my opinion somewhere in the same page where the contest begins, assumption created by my idea about M$ "fantasy").&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Problem&lt;/h3&gt;That Web Page literally insults other web browsers, even discarding, probably on purpose, &lt;a href="http://www.opera.com/"&gt;Opera&lt;/a&gt; one. In few words, that game is &lt;strong&gt;only for Internet Explorer 8 Users&lt;/strong&gt;. OK, OK, they are apparently desperate enough to pay users in order to have more market share, fair enough, but what is all this "fun" about others?&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;You'll never find it using &lt;strong&gt;old Firefox&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You'll never find it using &lt;strong&gt;boring Safari&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You'll never find it using &lt;strong&gt;tarnished Chrome&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Old Firefox&lt;/h3&gt;Growing up, day after day and biting points to IE market share, Firefox has always been an advanced browser, specially compared with Internet Explorer. Easy for everyone, powerful for developers, Firefox supports, for example, still in draft HTML 5 elements and W3 standards ... since ages!&lt;br /&gt;Internet Explorer 7 by the time was still suffering standards events, CSS 2 problems, and slow general responsiveness, over missed possibility for developers to debug properly. From Firefox, Internet Explorer 8 tried to copy a wonderful tool, Firebug, without having sames possibilities. Internet Explorer 8, compared with Firefox, has still W3 standards compatibility problems, a 5 times slower JavaScript engine, and lack of plug-ins to develop or simply surf more free.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Boring Safari&lt;/h3&gt;When you catalog a browser with such adjective, boring, it means you do not have arguments at all and you have been swallowed in the &lt;em&gt;kiddish gne, gne, gne&lt;/em&gt; twister unable to admit that "the boring one", is 2 laps around the world in front of you. The pioneer of CSS 3 transitions, effects, text properties, animations, one of the first to implement via WebKit guys (Gosh, I forgot to test &lt;a href="http://webkit.org/"&gt;WebKit&lt;/a&gt; there!!!) the new Squirrel Fish Engine, now Extreme in Safari 4, which is about 20 times faster than Internet Explorer ... but I forgot, boring is Safari because I guess boring is Mac OSX right? The Operating System famous for its native fluid user friendly special effects? Tha company that made iPhone, iPod, iWhatever, a must for everyone? Ooooohhhh Yes, that's boring!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Tarnished Chrome&lt;/h3&gt; ... wait a second, it's probably me .... let me think ... "&lt;em&gt;tarnished Chrome ... rome ... ome ... om&lt;/em&gt;". To be honest, when I read that, I though the creator of this Chrome dedicated version smoked a truly powerful drug, one of those drugs they write: use carefully in open spaces to avoid poisoning, but he rolled up the chemical stuff and that's the slogan: Avoid The Tarnished Chrome (The One With All Colorful Logo, Right?)&lt;br /&gt;I am sure this is the adjective about Google in Microsoft corridors, but still, only assumption. A browser that in few months is already between the third and the fourth position, rich of plugins, innovative ideas, is open source and again, it has a proper JavaScript engine, the V8 one, able to destroy in performance all Internet Explorers togheter!&lt;br /&gt;Which part is tarnished? Google is a "&lt;em&gt;neverendingmoving&lt;/em&gt;" company, which rather than block Web Development for at least 5 years is putting effort every day to make the Web a better, evoluted place (Silverlight possibly excluded, personal opinion).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Smell Of 90s Competition Page&lt;/h3&gt;Seriously, a competition which aim is to ask people to use Internet Explorer, rather than a website created only for Internet Explorer with, for example, @font-face instead of those old style images over hidden text ... I mean, &lt;strong&gt;what the hell is that&lt;/strong&gt;, a web page? I think all bad practices found a single page to be presented. Bad quality png, maybe this is for IE6, disproportionate use of images to make the page size about 140Kb, insults that only old IE8 users will appreciate for Who knows which reason (wake up guys), and a logic, a server side control, SO EFFICIENT, that simply using a userAgent switcher Firefox plugin I was &lt;a href="http://www.3site.eu/examples/FF35UA.png"&gt;able to emulate IE8 without receiving insults&lt;/a&gt;. Is this what you are looking for, a winner with Firebug, a plug-in to emulate Internet Explorer 8? What will happen if for some reason the winner will not use IE8? I am the author of vice-versa, for example, even emulate IE8 JScript is not a problem, with a more powerful browser, isn't it?&lt;br /&gt;&lt;br /&gt;&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/FzHown8JRXU&amp;hl=en&amp;fs=1&amp;"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/FzHown8JRXU&amp;hl=en&amp;fs=1&amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-8486053658357050725?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/8486053658357050725/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=8486053658357050725" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/8486053658357050725" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/8486053658357050725" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/JoZ5N0FePYs/one-with-microsoft-paying-users.html" title="The One With Microsoft Paying Users" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/06/one-with-microsoft-paying-users.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-6270400454467936312</id><published>2009-06-16T21:22:00.003+02:00</published><updated>2009-06-16T22:20:44.344+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Unite" /><category scheme="http://www.blogger.com/atom/ns#" term="Widget" /><category scheme="http://www.blogger.com/atom/ns#" term="opera" /><title type="text">Opera Unite ... or better, Server Widgets!</title><content type="html">My plan to conquer the World was so close that I could not believe it: the power of my old Centrino 1.6 based Laptop, nowadays less powerful than latest Netbook, plus my fantastic USB pen to surf constantly switching between GPRS, HSDPA, and 56Kb with constant lags of service, and finally a magic Web Server directly inside a good browser! WOW, It's Done!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What Blocked My Plans&lt;/h3&gt;... not the hardware, neither the connection, just the idea! First of all, I cannot understand (or maybe I can ...) that much why everybody should be excited by something like Opera Unite:&lt;ul&gt;&lt;li&gt;the idea is not new&lt;/li&gt;&lt;li&gt;the implementation is not that friendly&lt;/li&gt;&lt;li&gt;there are hundreds of limitations&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Nothing New&lt;/h3&gt;Somebody already complained about the &lt;em&gt;un-innovative&lt;/em&gt; service or the browser integrated web-server, I would like to add the good old &lt;a href="http://www.no-ip.com/"&gt;no-ip&lt;/a&gt; service to the list: install a Web Server, whatever it is, and as long as you are connected, no-ip will redirect a static url into your dynamic IP address. Easy? Moreover, you'll have full control over chosen programming languages, databases, etc etc. So which part of a unified sub domain into Opera servers redirected into your browser is that exciting?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Not That Friendly ... At All!&lt;/h3&gt;First of all, I think it is extremely ambiguous to put JavaScript files without understanding if these are for the server or for the client ... could be both? Who knows, I though the load event was for the global object ... what a surprise to find a load event specific for this internal web server. Something like addEventListener("webserver", function(){}); was too difficult to think about, wasn't it? If we would like to mess up our code, adding checks everywhere because we "do not know" how the file is going to be executed, that "load" event is the best option ever. Again, to test the application "&lt;em&gt;as is&lt;/em&gt;", apparently we need to put files into a file zip renamed .us - how comfortable for a language which main tradition is the one to be run-time interpreted ... No way, write code, zip, rename the archive, test ... and if a coma was wrong, redo from the scratch. &lt;strong&gt;I am sure I am missing something&lt;/strong&gt;, that was my first opinion as soon as I got how to create my first web app.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Too Many Limits&lt;/h3&gt;A local web-server, the key to save some money in this credit crunch era? And how can we do it if the second we "close the browser" all our data will be lost? &lt;strong&gt;Alternatives&lt;/strong&gt;:&lt;ol&gt;&lt;li&gt;storage mountPoint polled every N seconds in order to de-serialize data, add new one, if any, re-serialize, and save back again ... boring, not that safe, slow!&lt;/li&gt;&lt;li&gt;pray that the service, so far beta (alpha?) will never shut down, and use the finally never that usefull &lt;a href="http://www.jaql.org/release/0.2/jaql-overview.html"&gt;JSON Query library&lt;/a&gt;&lt;/li&gt;&lt;li&gt;ask Opera Engineers what's wrong with &lt;a href="http://dev.w3.org/html5/webstorage/#asynchronous-database-api"&gt;W3 Database API&lt;/a&gt;, considering we could implement an &lt;a href="http://www.sqlite.org/"&gt;SQLite&lt;/a&gt; file directly in the package, and copy in the storage folder if necessary. Just easy like that!&lt;/li&gt;&lt;li&gt;others, probably released with final version?&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;Moreover, everything is sandboxed via the xml configuration file ... but why on earth? OK, security, so we as hosts are considered not safe ... no-ip again? Folders limited somehow because of the event managment, we need a naming convetion. No Rewrite Rules possibility, and if I can add "myPage" event, will it be fired when I try "myPage/myName"? I do not know, Opera Unite crashed few seconds ago, I cannot try.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Maybe It Is Just Me&lt;/h3&gt;Yesterday I commented an arrogant post about JavaScript from PC Pro, today I am the arrogant one here and I am sorry if everything is because of my patience, vanished few seconds after I read the API and I did some test, but the impression is that since Opera Widgets are a good reality, this Opera Unite would like to make Widgets even closer to Developers, but in the server, it does not deal that well, IMHO. Anyway, there is still hope, this is a beta (alpha?), and hopefully good old Opera Pioneer will listen our opinion, improving our experience, and going forward thanks to our comments. Will it be the case?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-6270400454467936312?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/6270400454467936312/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=6270400454467936312" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6270400454467936312" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6270400454467936312" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/oJtMh0aX4XM/opera-unite-or-better-server-widgets.html" title="Opera Unite ... or better, Server Widgets!" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/06/opera-unite-or-better-server-widgets.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-1690662526268720045</id><published>2009-06-15T22:27:00.005+02:00</published><updated>2009-06-15T23:11:11.788+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="PC Pro" /><category scheme="http://www.blogger.com/atom/ns#" term="GWT" /><title type="text">On David Fearon PC Pro GWT Article</title><content type="html">I do not even know why somebody like me should buy PC Pro, maybe it was simply reminding me 12 years ago when I started fixing Hardware and Software problems as Computer Shop Technician? Maybe I was flying to Italy alone? It does not matter, nice enough I found, after years without reading it, an updated magazine which decided a while ago to talk about IT and Web as well, rather than only Hardware and few desktop applications.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Don't be afraid about Google latest web revolution&lt;/h3&gt;this is the title of the article, and the subject is not &lt;a href="http://wave.google.com/"&gt;wave&lt;/a&gt; but &lt;a href="http://code.google.com/webtoolkit/"&gt;GWT&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;JavaScript, the hideous language saved by browsers?&lt;/h3&gt;If you do not know a language, or you cannot spot its beauty, 'cause you only know a different one, in David case Java, you should not categorize JavaScript that bad.&lt;br /&gt;First of all, unlike David, I deeply know JavaScript, and I worked with both Java language and Java Developers, so I know what I am talking about, secondly, comparing a strongly typed programming language, Java, with one of the most successful, famous, omnipresent, and advanced scripting one, JavaScript, is an error that even a kid would not commit ... what are we talking about?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Even Google Prefers JavaScript And Does NOT Use GWT&lt;/h3&gt;at least this is what &lt;a href="http://ajaxian.com/archives/gwt-team-waves-goodbye-to-annoying-question-its-the-api-stupid"&gt;Ajaxian reported few days ago&lt;/a&gt;.&lt;br /&gt;Accordingly, if GWT and Java are "&lt;em&gt;that cool&lt;/em&gt;", I wonder why big G developers use raw JavaScript, which in mentioned article is described also as &lt;em&gt;the drudge that drains the fun out of web development&lt;/em&gt; ...&lt;br /&gt;Moreover, JavaScript is apparently an assembly language, in this era the language that the web can understand ... nothing about its simplicity, new amazing performances thanks to new engines, prototypal inheritance, nested closure, injectable scope, and all stuff that if you are not familiar with, you cannot even understand (neither comment badly, IMHO).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Tomato, Potato, and Pomato&lt;/h3&gt;I found that article for some reason interesting, not because it convinced me that JavaScript is a bad programming language, from scripting branch, just because I discovered how people could expose their opinion in such arrogant and not that competent way. PC Pro is still probably the best magazine out there, if we would like to be updated 360°, but please keep being neutral about subjects, whatever these are, you do not need to insult something you probably do not understand ... some reasonable comment could be enough, and that's it, don't you agree?&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Best Regards.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;P.S. "&lt;em&gt;Google has some of the best Ajax hackers out there&lt;/em&gt;", it cannot be true guys, I am not a Google developer so far :P&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-1690662526268720045?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/1690662526268720045/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=1690662526268720045" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/1690662526268720045" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/1690662526268720045" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/dCQfTeZ33lE/on-david-fearon-pc-pro-gwt-article.html" title="On David Fearon PC Pro GWT Article" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/06/on-david-fearon-pc-pro-gwt-article.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-6708918721190700727</id><published>2009-06-10T20:43:00.008+02:00</published><updated>2009-06-10T21:42:19.454+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="multiple" /><category scheme="http://www.blogger.com/atom/ns#" term="inheritance" /><title type="text">Wait A Moment, JavaScript Does Support Multiple Inheritance!</title><content type="html">... we are just doing it wrong!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Classical Inheritance? We Have Something Better!&lt;/h3&gt;The main limit about multiple inheritance in JavaScript is the presence of "&lt;em&gt;instanceof&lt;/em&gt;" operator. In a prototypal based inheritance objects simply inherits from objects, and &lt;em&gt;class&lt;/em&gt; keyword is almost meaningless.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// generic constructor&lt;br /&gt;function B(){};&lt;br /&gt;&lt;br /&gt;// remember the prototype&lt;br /&gt;var B1proto = B.prototype;&lt;br /&gt;&lt;br /&gt;// B instance&lt;br /&gt;var b1 = new B;&lt;br /&gt;&lt;br /&gt;// prototype reassignment&lt;br /&gt;B.prototype = {&lt;br /&gt;    constructor:B&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;// remember new prototype&lt;br /&gt;var B2proto = B.prototype;&lt;br /&gt;&lt;br /&gt;// B instance&lt;br /&gt;var b2 = new B;&lt;br /&gt;&lt;br /&gt;alert(b2 instanceof B); // true&lt;br /&gt;alert(b1 instanceof B); // false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Above snippet demonstrates how inheritance and instanceof are related to the current prototype, rather than the function/constructor itself.&lt;br /&gt;In few words, the function is the implicit init method for the current prototype object. The relation, as we could spot with FireFox, is with the prototype and not the used constructor.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// FireFox exposes __proto__&lt;br /&gt;// will be Object.getPrototypeOf&lt;br /&gt;// in ECMAScript 3.1&lt;br /&gt;b1.__proto__ == B1proto; // true&lt;br /&gt;b2.__proto__ == B2proto; // true&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Sure, And What About Multiple Inheritance?&lt;/h3&gt; ... I am going there, wait another few seconds :D&lt;br /&gt;Since the prototype is the relation, and not the constructor, and since a prototype is nothing but a common Object, we can add whatever method or property we want to this prototype object in order to obtain the hybrid one we are looking for.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;function A(){};&lt;br /&gt;A.prototype.name = "A instance";&lt;br /&gt;A.prototype.getName = function(){&lt;br /&gt;    return this.name;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;function B(){};&lt;br /&gt;B.prototype.name = "B instance";&lt;br /&gt;&lt;br /&gt;function C(){};&lt;br /&gt;// default name from B&lt;br /&gt;C.prototype.name = B.prototype.name;&lt;br /&gt;// getName from A&lt;br /&gt;C.prototype.getName = A.prototype.getName;&lt;br /&gt;// new method for C&lt;br /&gt;C.prototype.setName = function(name){&lt;br /&gt;    this.name = name;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;var c = new C();&lt;br /&gt;c.getName(); // B instance&lt;br /&gt;c.setName("Andrea");&lt;br /&gt;c.getName(); // Andrea&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In few words, we can add whatever we want to a prototype object creating exactly what multiple inheritance would create. We still have a problem with instanceof operator, don't we? Well, considering that "&lt;em&gt;instance&lt;/em&gt;" concept is something more meaningful in classical inheritance, we could say that it is not possible to emulate multiple inheritance Python like with JavaScript, but we can inject whatever method/property from whatever constructor.prototype, something not possible with Java, PHP, C#, and others ... so are we missing something?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;A Basic Object.implement Function Check&lt;/h3&gt;Due to the fact we could need to know if an hybrid instance is using this or that method, we could think about an abstract &lt;em&gt;implement&lt;/em&gt; method able to tell us if a generic instance constructor prototype, is at least implementing another constructor prototype, considering latter one as an &lt;strong&gt;interface&lt;/strong&gt;. If this is true, we are sure that we can use that instance/object in that way and without problems ... isn't it?&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;Object.implement = function(o, constructor){&lt;br /&gt;    // Another WebReflection Insane Snippet&lt;br /&gt;    if(o instanceof constructor)&lt;br /&gt;        // nothing to check&lt;br /&gt;        // classical boring stuff&lt;br /&gt;        return true;&lt;br /&gt;    // let's check if things are OK&lt;br /&gt;    var k, b = true,&lt;br /&gt;        // take the instance constructor prototype&lt;br /&gt;        po = o.constructor.prototype,&lt;br /&gt;        // take the implemented prototype&lt;br /&gt;        pc = constructor.prototype&lt;br /&gt;    ;&lt;br /&gt;    // for each property or method&lt;br /&gt;    // in the implemented constructor&lt;br /&gt;    for(k in pc)&lt;br /&gt;        // check if the instance inherited prototype&lt;br /&gt;        // has this method/property as well&lt;br /&gt;        b = b &amp;&amp; k in po; //* TOTHINK: */ &amp;&amp; (typeof po[k] === typeof pc[k]); //*/&lt;br /&gt;    // if there was nothing to check&lt;br /&gt;    // we cannot say a word ... but ...&lt;br /&gt;    // if instance has every method/property&lt;br /&gt;    // present in the compared constructor&lt;br /&gt;    // prototype, we could say this instance&lt;br /&gt;    // implements this constructor&lt;br /&gt;    return !!k &amp;&amp; b;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Purist Classical OOP Developers are probably already rolling around the floor in pain and screaming &lt;em&gt;he's f#@*in idiot&lt;/em&gt;, but what is the meaning of implement in classical inheritance patterns?&lt;br /&gt;&lt;strong&gt;&lt;a href="http://en.wikipedia.org/wiki/Interface_(Java)"&gt;Wikipedia - Interface&lt;/a&gt;&lt;/strong&gt;&lt;br /&gt;&lt;blockquote cite="wikipedia"&gt;&lt;br /&gt;Interfaces are used to encode similarities which classes of various types share, but do not necessarily constitute a class relationship&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;In few words my latest snippet checks if an object contains every method/property defined in another object so, using first example, we could do:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// add noise and chaos with another constructor ...&lt;br /&gt;function D(){};&lt;br /&gt;D.prototype.notInObject = true;&lt;br /&gt;&lt;br /&gt;// check Object.implement ...&lt;br /&gt;Object.implement(c, A); // true&lt;br /&gt;Object.implement(c, B); // true&lt;br /&gt;Object.implement(c, C); // true&lt;br /&gt;Object.implement(c, D); // false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Nothing new? Nothing true? Is it clear for everybody? 8-)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-6708918721190700727?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/6708918721190700727/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=6708918721190700727" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6708918721190700727" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6708918721190700727" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/y4Ouyp0hbvc/wait-moment-javascript-does-support.html" title="Wait A Moment, JavaScript Does Support Multiple Inheritance!" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/06/wait-moment-javascript-does-support.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-8978499410792681372</id><published>2009-06-10T00:40:00.004+02:00</published><updated>2009-06-10T01:18:14.156+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="TreePanel" /><category scheme="http://www.blogger.com/atom/ns#" term="Internet Explorer" /><category scheme="http://www.blogger.com/atom/ns#" term="ExtJS" /><category scheme="http://www.blogger.com/atom/ns#" term="events" /><category scheme="http://www.blogger.com/atom/ns#" term="arrow" /><title type="text">ExtJS And The Bloody TreePanel Arrow</title><content type="html">First of all I am sorry for choose title, but I kinda lost dunno how many minutes to figure out &lt;strong&gt;what was wrong&lt;/strong&gt;, and &lt;strong&gt;it was not me&lt;/strong&gt;!&lt;br /&gt;Please let me try to explain what was the requirement, and how I had to force ExtJS to act as I want, &lt;strong&gt;version 2.2.1 or 3.0RC2&lt;/strong&gt;, it does not matter.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Problem ...&lt;/h3&gt;The reason you or your company choose ExtJS is most likely because of its Office $uite / Window$ look and feel, closer than many others to a proper Desktop Application, perfect under Adobe Air, and one step forward about stability, performances, and documentation, even with the old enemy: Internet Explorer &lt;strong&gt;6&lt;/strong&gt;. Fair enough, it's a good library but, there is always a but, at the same time it does not replicate 100% same Window$ behaviors.&lt;br /&gt;As example, try to click Start and Run a prompt command, &lt;strong&gt;explorer&lt;/strong&gt;.&lt;br /&gt;This is the typical Window$ file browser, something we deal with since ages, something still a user habit.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;... In Details&lt;/h3&gt;How does it work? It is really simple, we have a representation of our files in the left, let's call it Tree, and many details on the right but &lt;strong&gt;only if we click a folder&lt;/strong&gt;. That is the problem, the Jurassic explorer acts differently if &lt;strong&gt;we click the [+] rather than the folder/file&lt;/strong&gt;. The difference is that while we are simply surfing a Tree structure, we do not need to show every single detail, preview, whatever, on the right side until we click, still on the left side, into the folder we need.&lt;br /&gt;As summary, one click on the [+] to open the folder, one to [-] to close it, if we click the folder and it is closed, it will be opened as if we pressed the [+] and the right side will change showing details about that folder. Morevore, if we do a double click, nothing happen, the explorer works with click, and eventually right click. Seems to be truly simple, isn't it? &lt;strong&gt;It's NOT&lt;/strong&gt;, unless I am missing an hidden part of ExtJS documentation because I swear I tried everything.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Ext.tree.TreePanel Hacked To Have More Control Over The Arrow&lt;/h3&gt;... where the rrow is the one in ExtJS 2, in version 3 they put a lovely [+]/[-] which reminds even more explorer surfing!!! I am not here to judge ExtJS choices, I am just writing my solution to this problem, specially because &lt;a href="http://twitter.com/tdginnovations"&gt;tdginnovations&lt;/a&gt; asked me, via twitter, to make this problem public, with solution as well.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;// good old onload ...&lt;br /&gt;onload = function(){&lt;br /&gt;&lt;br /&gt;// simple function to add nodes&lt;br /&gt;// just for this example&lt;br /&gt;function addNodes(root, dummyData){&lt;br /&gt;    for(var&lt;br /&gt;        i = 0, length = dummyData.length,&lt;br /&gt;        cls = {true:"file",false:"folder"},&lt;br /&gt;        data, leaf;&lt;br /&gt;        i &lt; length; ++i&lt;br /&gt;    ){&lt;br /&gt;        data = dummyData[i];&lt;br /&gt;        leaf = root.appendChild(new Ext.tree.TreeNode({&lt;br /&gt;            text:data.text,&lt;br /&gt;            leaf:!data.items,&lt;br /&gt;            cls:cls[!data.items]&lt;br /&gt;        }));&lt;br /&gt;        if(data.items)&lt;br /&gt;            addNodes(leaf, data.items);&lt;br /&gt;    };&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;var&lt;br /&gt;    // just a sync example&lt;br /&gt;    // with a couple of folders&lt;br /&gt;    dummyData = [&lt;br /&gt;        {text:"Test 1", items:[&lt;br /&gt;            {text:"Sub Test 1 1"},&lt;br /&gt;            {text:"Sub Test 1 2"}&lt;br /&gt;        ]},&lt;br /&gt;        {text:"Test 2"},&lt;br /&gt;        {text:"Test 3", items:[&lt;br /&gt;            {text:"Sub Test 3 1"},&lt;br /&gt;            {text:"Sub Test 3 2", items:[&lt;br /&gt;                {text:"Sub Test 3 2 1"},&lt;br /&gt;                {text:"Sub Test 3 2 2"}&lt;br /&gt;            ]},&lt;br /&gt;            {text:"Sub Test 3 3"}&lt;br /&gt;        ]}&lt;br /&gt;    ],&lt;br /&gt;    &lt;br /&gt;    // the lovely TreePanel&lt;br /&gt;    TreePanel = new Ext.tree.TreePanel({&lt;br /&gt;        renderTo:document.body,&lt;br /&gt;        border:false,&lt;br /&gt;        rootVisible: false,&lt;br /&gt;        root:{&lt;br /&gt;            expanded: true,&lt;br /&gt;            text: "",&lt;br /&gt;            draggable: false&lt;br /&gt;        },&lt;br /&gt;        &lt;br /&gt;        // global TreePanel events&lt;br /&gt;        listeners:{&lt;br /&gt;        &lt;br /&gt;            // Hack #1: The Lovely Arrow ..&lt;br /&gt;        &lt;br /&gt;            // here starts the open hack ...&lt;br /&gt;            // when the arrow is clicked,&lt;br /&gt;            // no click event is propagated&lt;br /&gt;            // but when the node is clicked&lt;br /&gt;            // beforeexpandnode is called ...&lt;br /&gt;            // to avoid troubles I used a flag&lt;br /&gt;            // in order to discard next&lt;br /&gt;            // beforeexpandnode event&lt;br /&gt;            // without returning false&lt;br /&gt;            // but if this is the arrow&lt;br /&gt;            // without the click ... so&lt;br /&gt;            // the lonely beforeexpandnode ...&lt;br /&gt;            beforeexpandnode:function(Node){&lt;br /&gt;                // check if the flag is not setted&lt;br /&gt;                if(!Node.beforeexpandnode){&lt;br /&gt;                    // set the flag, prevent&lt;br /&gt;                    // return false onclick event&lt;br /&gt;                    Node.beforeexpandnode = true;&lt;br /&gt;                    // fire the click event&lt;br /&gt;                    // the one in charge&lt;br /&gt;                    // to load or show stuff&lt;br /&gt;                    Node.fireEvent("click", Node);&lt;br /&gt;                    // block this call&lt;br /&gt;                    // or we gonna open twice ...&lt;br /&gt;                    // with possible loops&lt;br /&gt;                    // (at least in Ext 2.2.1)&lt;br /&gt;                    return false;&lt;br /&gt;                }&lt;br /&gt;            },&lt;br /&gt;            // here we are ...&lt;br /&gt;            // if it was a click in the name/folder/leaf&lt;br /&gt;            // this event is fired before beforeexpandnode&lt;br /&gt;            // we need to check a couple of things ... &lt;br /&gt;            click:function(Node, e){&lt;br /&gt;                // if node is expanded&lt;br /&gt;                // we do not need to do anything&lt;br /&gt;                if(Node.isExpanded()){&lt;br /&gt;                    console.log("already expanded");&lt;br /&gt;                }&lt;br /&gt;                // but if node is not expanded&lt;br /&gt;                // and the beforeexpandnode flag &lt;br /&gt;                // has been setted as true ...&lt;br /&gt;                else if(Node.beforeexpandnode) {&lt;br /&gt;                    // we know that this click&lt;br /&gt;                    // is from the arrow, and not&lt;br /&gt;                    // from the folder or name&lt;br /&gt;                    console.log("expand via arrow/plus or minus");&lt;br /&gt;                    // we can load stuff async, putting&lt;br /&gt;                    // a mask to the panel before, removing it&lt;br /&gt;                    // on load success, add nodes&lt;br /&gt;                    // and finally expand this Node&lt;br /&gt;                    // this if should not exists if&lt;br /&gt;                    // the node is a leaf, cause there&lt;br /&gt;                    // is no arrow beside&lt;br /&gt;                    Node.expand();&lt;br /&gt;                }&lt;br /&gt;                // if node is not expanded but it is&lt;br /&gt;                // a folder and beforeexpandnode flag&lt;br /&gt;                // has not been setted as true&lt;br /&gt;                // we know that the user performed&lt;br /&gt;                // a click ...&lt;br /&gt;                else if(!Node.isLeaf()) {&lt;br /&gt;                    // to avoid another click event&lt;br /&gt;                    // triggered via beforeexpandnode event&lt;br /&gt;                    // we need to set the flag as true&lt;br /&gt;                    // so beforeexpandnode will not&lt;br /&gt;                    // return false calling this event&lt;br /&gt;                    // again (precedent if)&lt;br /&gt;                    Node.beforeexpandnode = true;&lt;br /&gt;                    // at this point we could perform&lt;br /&gt;                    // a different request&lt;br /&gt;                    // which could return the entire node&lt;br /&gt;                    // list plus some other information&lt;br /&gt;                    // or simply do something else&lt;br /&gt;                    // rather than just populate the &lt;br /&gt;                    // Node with sub-nodes&lt;br /&gt;                    console.log("expand via click");&lt;br /&gt;                    // in this case, let's expand the node&lt;br /&gt;                    Node.expand();&lt;br /&gt;                }&lt;br /&gt;                // none of precedent condition&lt;br /&gt;                // was true, interesting ...&lt;br /&gt;                // ... it must be just a leaf ;)&lt;br /&gt;                else {&lt;br /&gt;                    // let's do something&lt;br /&gt;                    // with this leaf&lt;br /&gt;                    console.log(Node.text);&lt;br /&gt;                };&lt;br /&gt;                // the main problem with click&lt;br /&gt;                // is that it is not possible&lt;br /&gt;                // to avoid a double click&lt;br /&gt;                // e.stopEvent() ? no way&lt;br /&gt;                // it does not do anything with&lt;br /&gt;                // dblclick, useless&lt;br /&gt;            },            &lt;br /&gt;            // last part of this little hack ...&lt;br /&gt;            // once the node is expanded&lt;br /&gt;            // it makes sense to &lt;br /&gt;            // set the flag as false&lt;br /&gt;            // so next beforeexpandnode event&lt;br /&gt;            // will work as expected&lt;br /&gt;            expandnode:function(Node){&lt;br /&gt;                Node.beforeexpandnode = false;&lt;br /&gt;            },&lt;br /&gt;            &lt;br /&gt;            // Hack #2: ... I said:&lt;br /&gt;            // DO NOT CLOSE ON DOUBLE CLICK!!!&lt;br /&gt;            &lt;br /&gt;            // at least this hack is even shorter&lt;br /&gt;            // but it still requires 2 events&lt;br /&gt;            // dblclick, as I said, cannot be&lt;br /&gt;            // stopped ... but it does not&lt;br /&gt;            // really matter, cause&lt;br /&gt;            // beforecollapsenode will be fired&lt;br /&gt;            // always before ... so, even&lt;br /&gt;            // implementing a proper stopEvent&lt;br /&gt;            // how could we avoid closing action&lt;br /&gt;            // from beforecollapsenode event&lt;br /&gt;            // since this is fired before &lt;br /&gt;            // dblclick?&lt;br /&gt;            &lt;br /&gt;            // dblclick has to be a sort&lt;br /&gt;            // of filter able to change&lt;br /&gt;            // another flag&lt;br /&gt;            // beforecollapsenode&lt;br /&gt;            // if node is expanded&lt;br /&gt;            // we set the flag as false&lt;br /&gt;            // why ? ... read next ...&lt;br /&gt;            dblclick:function(Node, e){&lt;br /&gt;                if(Node.isExpanded())&lt;br /&gt;                    Node.beforecollapsenode = false;&lt;br /&gt;            },&lt;br /&gt;            &lt;br /&gt;            // beforecollapsenode event&lt;br /&gt;            // is fired before dblclick&lt;br /&gt;            // so this hack is about milliseconds.&lt;br /&gt;            // if the flag is not set&lt;br /&gt;            // we set it as true and we call a timetout&lt;br /&gt;            // Hopefully, the double click will be performed&lt;br /&gt;            // before choose timeout.&lt;br /&gt;            // If this happens, it means&lt;br /&gt;            // that the user double clicked the&lt;br /&gt;            // opened node, otherwise&lt;br /&gt;            // it means that the user did not&lt;br /&gt;            // mean a double click (the arrow&lt;br /&gt;            // does NOT fire a dblclick in any case)&lt;br /&gt;            // while He/She simpl clicked once in&lt;br /&gt;            // the arrow (or more than once to close it)&lt;br /&gt;            beforecollapsenode:function(Node){&lt;br /&gt;                if(!Node.beforecollapsenode){&lt;br /&gt;                    Node.beforecollapsenode = true;&lt;br /&gt;                    setTimeout(function(){&lt;br /&gt;                        // so here this hack should&lt;br /&gt;                        // perform its action ...&lt;br /&gt;                        if(Node.beforecollapsenode)&lt;br /&gt;                            // closing the node&lt;br /&gt;                            // if it was not a dblclick&lt;br /&gt;                            Node.collapse();&lt;br /&gt;                    }, 20);&lt;br /&gt;                    return false;&lt;br /&gt;                }&lt;br /&gt;            },&lt;br /&gt;            // to complete the task&lt;br /&gt;            // let's reset status &lt;br /&gt;            // on node collapsed&lt;br /&gt;            collapsenode:function(Node){&lt;br /&gt;                Node.beforecollapsenode = false;&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    })&lt;br /&gt;;&lt;br /&gt;&lt;br /&gt;// it's time to test&lt;br /&gt;addNodes(TreePanel.getRootNode(), dummyData);&lt;br /&gt;// and play with this version&lt;br /&gt;TreePanel.render();&lt;br /&gt;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That's it, waiting for comments, better examples, or even solution I could not think about!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-8978499410792681372?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/8978499410792681372/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=8978499410792681372" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/8978499410792681372" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/8978499410792681372" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/GqTVdLXh0Tk/extjs-and-bloody-treepanel-arrow.html" title="ExtJS And The Bloody TreePanel Arrow" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/06/extjs-and-bloody-treepanel-arrow.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-1595919961403770650</id><published>2009-06-07T22:29:00.006+02:00</published><updated>2009-06-07T23:28:16.563+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="MySQL" /><category scheme="http://www.blogger.com/atom/ns#" term="INSERT" /><category scheme="http://www.blogger.com/atom/ns#" term="UPDATE" /><category scheme="http://www.blogger.com/atom/ns#" term="DELAYED" /><title type="text">MySQL UPDATE DELAYED - Just My Solution</title><content type="html">&lt;h3&gt;The Problem&lt;/h3&gt;MySQL supports &lt;a href="http://dev.mysql.com/doc/refman/5.1/en/insert-delayed.html"&gt;DELAYED&lt;/a&gt; option as &lt;strong&gt;INSERT&lt;/strong&gt; statement but, for some obscure reason nobody got so far, it does not support &lt;strong&gt;UPDATE DELAYED&lt;/strong&gt; or DELETE DELAYED.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Why DELAYED Is Necessary&lt;/h3&gt;As quick summary, INSERT DELAYED is something truly useful when we would like to let MySQL decide when it is time to perform that insert without blocking tables and users. This is a problem almost specific for engines like MyISAM, MEMORY, ARCHIVE, and BLACKHOLE. This post is not about "&lt;em&gt;why not InnoDB&lt;/em&gt;", this is about DELAYED with these engines, specially with MyISAM one.&lt;br /&gt;To better understand a common case where an UPDATE DELAYED could be extremely useful, just think about a counter, how many users visited that id. Is such information that useful to be not approximated and to possibly block every other select because of an update that nobody will verify with a microscope? In my opinion, such information is "just a plus" and if the page execution could be faster without blocking anybody and putting those UPDATES in a queue as is for INSERT DELAYED in order to perform it in a shot and in "the best moment ever" ... why on earth we should have not such option?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;UPDATE LOW_PRIORITY Is NOT The Same&lt;/h3&gt;Unfortunately, we could choose to let the user wait a bit more thanks to LOW_PRIORITY option with an UPDATE statement but still: why that user should wait more for such irrelevant information?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Split The Problem! That's My Idea&lt;/h3&gt;Apparently there are no good options to emulate an UPDATE DELAYED with MySQL so I tried to use INSERT DELAYED plus some trick able to delegate the LOW_PRIORITY update to somebody else (crontab or database via event), without blocking any user and making page response faster with hundreds of thousands of rows for a single static table.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Example Tables&lt;/h3&gt;Try to imagine we have a generic service based on an &lt;strong&gt;id&lt;/strong&gt;, which is unique and used in every other part of the database as main relation. Now for this id we could have other N fields, it does not matter, as long as we use a total field to know how many users visited that id.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;CREATE TABLE IF NOT EXISTS counter (&lt;br /&gt;    id INT(10) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY,&lt;br /&gt;    /* one or more fields (possibly static) */&lt;br /&gt;    total INT(3) UNSIGNED NOT NULL&lt;br /&gt;) ENGINE=MyISAM;&lt;br /&gt;&lt;br /&gt;/* let's populate the counter table with 3 ids */&lt;br /&gt;INSERT INTO counter (total) VALUES (0), (0), (0);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The &lt;strong&gt;REPLACE DELAYED&lt;/strong&gt; query will be a suicide for a big table with thousands of records, while INSERT DELAYED cannot be performed in the main table or every key will be duplicated for N times. To perform an INSERT DELAYED we need then another table, with &lt;strong&gt;just a single field&lt;/strong&gt;, possibly the same type used for the main key, in this example the id.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/* specific table for delayed inserts */&lt;br /&gt;CREATE TABLE IF NOT EXISTS counter_total (&lt;br /&gt;    id INT(10) UNSIGNED NOT NULL,&lt;br /&gt;    KEY id (id)&lt;br /&gt;) ENGINE=MyISAM;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;/* visits for ids,  3 users in id 1, 2 in id 2, 1 in id 3 */&lt;br /&gt;INSERT DELAYED INTO counter_total VALUES (1);&lt;br /&gt;INSERT DELAYED INTO counter_total VALUES (2);&lt;br /&gt;INSERT DELAYED INTO counter_total VALUES (1);&lt;br /&gt;INSERT DELAYED INTO counter_total VALUES (3);&lt;br /&gt;INSERT DELAYED INTO counter_total VALUES (2);&lt;br /&gt;INSERT DELAYED INTO counter_total VALUES (1);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Last INSERTs are to emulate 6 users visiting id 1 3 times, id 2 twice, and id 3 only once. Since we are using INSERT DELAYED it does not matter how many users are surfing the page and how many are in the same id, we simply do not care and we let MySQL decide when it is about the time to shot every insert in one go for the WRITE ONLY table, counter_total. Moreover, since the main id is the key for this solution, the query is so simple that its execution time will be extremely fast, even in my laptop.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Every N Seconds, Minutes, Hours ...&lt;/h3&gt;At this point the counter_total table will contain N main id&lt;em&gt;s&lt;/em&gt;, what we have to do know is:&lt;ol&gt;&lt;br /&gt;&lt;li&gt;block possible insert delayed locking the counter_total table&lt;/li&gt;&lt;br /&gt;&lt;li&gt;have a snapshot of visited ids and total visit, via function COUNT&lt;/li&gt;&lt;br /&gt;&lt;li&gt;reset counter_total to keep it small and fast&lt;/li&gt;&lt;br /&gt;&lt;li&gt;release counter_total to allow queued INSERT DELAYED to be executed&lt;/li&gt;&lt;br /&gt;&lt;li&gt;find a way to quickly update with low_priority the main counter table&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;To solve above points we could use a TEMPORARY TABLE created directly with ENGINE=MEMORY. This will ensure us CPU+RAM speed performances without using that big amount of RAM in any case (if we do, we need to reduce the delay between one call and another one).&lt;br /&gt;Here is the sequence to perform the entire operation in a flash!&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;/* WebReflection UPDATE DELAYED Workaround */&lt;br /&gt;CREATE TEMPORARY TABLE tmp_counter (&lt;br /&gt;    id INT(10) UNSIGNED NOT NULL,&lt;br /&gt;    total INT(3) UNSIGNED NOT NULL&lt;br /&gt;) ENGINE=MEMORY;&lt;br /&gt;LOCK TABLE counter_total WRITE;&lt;br /&gt;INSERT INTO&lt;br /&gt;    tmp_counter (&lt;br /&gt;        SELECT&lt;br /&gt;            counter_total.id,&lt;br /&gt;            COUNT(counter_total.id)&lt;br /&gt;        FROM&lt;br /&gt;            counter_total&lt;br /&gt;        GROUP BY&lt;br /&gt;            counter_total.id&lt;br /&gt;    )&lt;br /&gt;;&lt;br /&gt;DELETE FROM counter_total;&lt;br /&gt;UNLOCK TABLE;&lt;br /&gt;UPDATE LOW_PRIORITY&lt;br /&gt;    counter AS c&lt;br /&gt;LEFT JOIN&lt;br /&gt;    tmp_counter AS tc&lt;br /&gt;ON(&lt;br /&gt;    c.id = tc.id&lt;br /&gt;)&lt;br /&gt;SET&lt;br /&gt;    c.total = (&lt;br /&gt;        c.total + tc.total&lt;br /&gt;    )&lt;br /&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;That's it, tested over hundred of thousands of records in a reasonable &lt;strong&gt;0.2&lt;/strong&gt; time and with an old laptop that apparently, if "used" properly, can still give me a lot :P&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;As Summary&lt;/h3&gt;A counter is a classic example where an UPDATE DELAYED could be useful. Unfortunately MySQL does not support it (probably version 6) so we can use the supported INSERT DELAYED (please note with replication will be a normal INSERT due to synchronization problems but it will be for a write only table). To do this, we need to create another table and lock it when we decide that it is about the time to update the main one. With a truly simple sequence of queries, this could be a super fast operation, rather than a bottleneck if for some reason 100 users are visiting our website with "inline update".&lt;br /&gt;&lt;br /&gt;Now, do you have a better solution? If Yes, please share it, thanks ;)&lt;br /&gt;&lt;br /&gt;P.S. I need to say thanks to Olga for the temporary suggestion, I was almost struggling with missed MyISAM transactions :D&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-1595919961403770650?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/1595919961403770650/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=1595919961403770650" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/1595919961403770650" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/1595919961403770650" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/SXetR5xvaFI/mysql-update-delayed-just-my-solution.html" title="MySQL UPDATE DELAYED - Just My Solution" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/06/mysql-update-delayed-just-my-solution.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-7224463369853662518</id><published>2009-06-05T23:40:00.007+02:00</published><updated>2009-06-06T13:48:37.760+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="wrong" /><category scheme="http://www.blogger.com/atom/ns#" term="onload" /><category scheme="http://www.blogger.com/atom/ns#" term="friendly" /><category scheme="http://www.blogger.com/atom/ns#" term="usable" /><category scheme="http://www.blogger.com/atom/ns#" term="focus" /><category scheme="http://www.blogger.com/atom/ns#" term="not" /><title type="text">input.focus() ... something really annoying!</title><content type="html">new libraries, new add-on&lt;em&gt;s&lt;/em&gt;, new engines, new browsers, but &lt;strong&gt;still the bloody focus event directly in the onload one&lt;/strong&gt; ... any chance we will go a step forward?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What is wrong with focus&lt;/h3&gt;The main usage of this strategy is to force via JavaScript the focus of the main input field and it is usually on the top of the page.&lt;br /&gt;It could be a search input, a la Google, or it could be a generic log-in. It could be a blog post title, or it could be a comment ... whatever it is, &lt;strong&gt;it should NOT act like this!&lt;/strong&gt;&lt;br /&gt;Try to imagine you have a slow connection (I am still with mobile usb pen) or try to imagine you are using your A Grade browser mobile phone with still, a not that fast connection (I am still using my Android, iPhone is the same).&lt;br /&gt;Since these magic-focused fields are usually at the beginning of the page and since the page will take more time to be downloaded, 90% of the time this automatic feature messes up my user and password or my searched keyword. &lt;strong&gt;Too often I have to correct or change back the field&lt;/strong&gt;, specially when I need to log-in into my on-line banking service, where my actions are faster than page download. Am I that fast? OK, Android first model with its pretty keyboard let me type faster than how I could do with iPhone or second Android generation, but the main problem is that if there is an image, for example, or generally speaking just content after main focused input, the onload event will be fired too late and &lt;strong&gt;it will be completely useless and inefficient&lt;/strong&gt;, rather than being an help for the user.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;How could we solve the problem&lt;/h3&gt;In my opinion, it is the most simple thing ever. Assuming that the &lt;em&gt;theoretically helping focus&lt;/em&gt; will be only one per page, if the site would like to make sense, all we need is a little manager able to understand if &lt;strong&gt;the input received focus before the onload event&lt;/strong&gt;:&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;form name=&amp;quot;f&amp;quot; action=&amp;quot;/search&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;input name=&amp;quot;q&amp;quot; onfocus=&amp;quot;fff=1&amp;quot; /&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;acronym title="Field First Focus"&gt;fff&lt;/acronym&gt; will be a global variable which name is absolutely irrelevant and which aim will be to stop the generic onload event to force focus in that input.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;body onload=&amp;quot;if(!this.fff)document.f.q.focus();&amp;quot;&amp;gt;&lt;br /&gt;    &amp;lt;!-- ... the rest of the page ... --&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With a zero effort + stress strategy that will not increase more than a couple of bytes our page, users will have more control over their fields. This simple trick could be used for every textarea, input, select, or button in the page making the auto focus really helpful in those case user has a fast connection or is lazy and does not want to point the focus automatically, rather than quick posts via mobile or slow connections.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Another Way Without Changing Every Layout&lt;/h3&gt;&lt;br /&gt;I agree that probably nobody will ever change every page layout adding an inline onfocus event for each field, so here I am with a better solution that should be widely copatible with every kind of device.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;(function(){&lt;br /&gt;// A WebReflection Anti Stress Idea&lt;br /&gt;function onclick(e){&lt;br /&gt;    var target = (e &amp;amp;&amp;amp; e.target) || event.srcElement;&lt;br /&gt;    if(/^(input|select|textarea|button)$/i.test(target.nodeName)){&lt;br /&gt;        window.fff = true;&lt;br /&gt;        if(document.detachEvent)&lt;br /&gt;            document.detachEvent(&amp;quot;onclick&amp;quot;, onclick);&lt;br /&gt;        else&lt;br /&gt;            document.removeEventListener(&amp;quot;click&amp;quot;, onclick, false);&lt;br /&gt;    }&lt;br /&gt;};&lt;br /&gt;if(document.attachEvent)&lt;br /&gt;    document.attachEvent(&amp;quot;onclick&amp;quot;, onclick);&lt;br /&gt;else&lt;br /&gt;    document.addEventListener(&amp;quot;click&amp;quot;, onclick, false);&lt;br /&gt;})();&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;// as body or window event&lt;br /&gt;onload = function(){&lt;br /&gt;    if(!this.fff)&lt;br /&gt;        document.getElementById(&amp;quot;main-input&amp;quot;).focus();&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Above snippet does not require both onReady or onload events so it should work just adding it inside the head tag. It is so simple, now let's see how people will react 8)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-7224463369853662518?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/7224463369853662518/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=7224463369853662518" title="9 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/7224463369853662518" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/7224463369853662518" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/hGDES4fmnP8/inputfocus-something-really-annoying.html" title="input.focus() ... something really annoying!" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">9</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/06/inputfocus-something-really-annoying.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-7081271171563878935</id><published>2009-05-27T00:20:00.014+02:00</published><updated>2009-05-28T12:17:33.270+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="blog" /><category scheme="http://www.blogger.com/atom/ns#" term="post" /><category scheme="http://www.blogger.com/atom/ns#" term="safe" /><category scheme="http://www.blogger.com/atom/ns#" term="postable" /><category scheme="http://www.blogger.com/atom/ns#" term="encode" /><title type="text">en-code: the quickest way to encode your snippet</title><content type="html">&lt;strong&gt;Update&lt;/strong&gt; I have created an inline callback that could be used to show en-code in every page or as bookmark:&lt;br /&gt;&lt;a href="javascript&amp;#58;(function(src&amp;#44;w&amp;#44;h&amp;#44;i&amp;#44;s)&amp;#123;if(this.WebReflectionEncode)return&amp;#32;this.WebReflectionEncode()&amp;#59;function&amp;#32;p()&amp;#123;s.top&amp;#61;(document.documentElement.scrollTop&amp;#124;&amp;#124;(document.body&amp;#38;&amp;#38;document.body.scrollTop)&amp;#124;&amp;#124;0)&amp;#43;'px'&amp;#125;&amp;#59;try&amp;#123;i&amp;#61;document.createElement('&amp;#60;iframe&amp;#32;frameborder&amp;#61;&amp;#34;0&amp;#34;&amp;#32;src&amp;#61;&amp;#34;'&amp;#43;src&amp;#43;'&amp;#34;&amp;#62;&amp;#60;&amp;#47;iframe&amp;#62;')&amp;#125;catch(e)&amp;#123;i&amp;#61;document.createElement('iframe')&amp;#59;i.src&amp;#61;src&amp;#125;&amp;#59;s&amp;#61;i.style&amp;#59;s.border&amp;#61;'1px&amp;#32;solid&amp;#32;black'&amp;#59;s.width&amp;#61;w&amp;#43;'px'&amp;#59;s.height&amp;#61;h&amp;#43;'px'&amp;#59;s.position&amp;#61;'absolute'&amp;#59;s.right&amp;#61;0&amp;#59;s.zIndex&amp;#61;99999&amp;#59;p()&amp;#59;w&amp;#61;setInterval(p&amp;#44;250)&amp;#59;(document.body&amp;#124;&amp;#124;document.documentElement).appendChild(i)&amp;#59;this.WebReflectionEncode&amp;#61;function()&amp;#123;clearInterval(w)&amp;#59;i.parentNode.removeChild(i)&amp;#59;w&amp;#61;h&amp;#61;s&amp;#61;i&amp;#61;null&amp;#59;this.WebReflectionEncode&amp;#61;null&amp;#59;&amp;#125;&amp;#125;)('http&amp;#58;&amp;#47;&amp;#47;www.3site.eu&amp;#47;encode&amp;#47;'&amp;#44;280&amp;#44;320)&amp;#59;"&gt;WebReflection::encode&lt;/a&gt; (just a click to give it a try)&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;javascript&amp;#58;(function(src&amp;#44;w&amp;#44;h&amp;#44;i&amp;#44;s)&amp;#123;if(this.WebReflectionEncode)return&amp;#32;this.WebReflectionEncode()&amp;#59;function&amp;#32;p()&amp;#123;s.top&amp;#61;(document.documentElement.scrollTop&amp;#124;&amp;#124;(document.body&amp;#38;&amp;#38;document.body.scrollTop)&amp;#124;&amp;#124;0)&amp;#43;'px'&amp;#125;&amp;#59;try&amp;#123;i&amp;#61;document.createElement('&amp;#60;iframe&amp;#32;frameborder&amp;#61;&amp;#34;0&amp;#34;&amp;#32;src&amp;#61;&amp;#34;'&amp;#43;src&amp;#43;'&amp;#34;&amp;#62;&amp;#60;&amp;#47;iframe&amp;#62;')&amp;#125;catch(e)&amp;#123;i&amp;#61;document.createElement('iframe')&amp;#59;i.src&amp;#61;src&amp;#125;&amp;#59;s&amp;#61;i.style&amp;#59;s.border&amp;#61;'1px&amp;#32;solid&amp;#32;black'&amp;#59;s.width&amp;#61;w&amp;#43;'px'&amp;#59;s.height&amp;#61;h&amp;#43;'px'&amp;#59;s.position&amp;#61;'absolute'&amp;#59;s.right&amp;#61;0&amp;#59;s.zIndex&amp;#61;99999&amp;#59;p()&amp;#59;w&amp;#61;setInterval(p&amp;#44;250)&amp;#59;(document.body&amp;#124;&amp;#124;document.documentElement).appendChild(i)&amp;#59;this.WebReflectionEncode&amp;#61;function()&amp;#123;clearInterval(w)&amp;#59;i.parentNode.removeChild(i)&amp;#59;w&amp;#61;h&amp;#61;s&amp;#61;i&amp;#61;null&amp;#59;this.WebReflectionEncode&amp;#61;null&amp;#59;&amp;#125;&amp;#125;)('http&amp;#58;&amp;#47;&amp;#47;www.3site.eu&amp;#47;encode&amp;#47;'&amp;#44;280&amp;#44;320)&amp;#59;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;P.S. WOW, to make it possible I had to use raw format ... at least now the bookmark link seems to work fine in every browser!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;What am I talking about?&lt;/h3&gt;We, as developers, too often post code in this or that website/blog, and often we loose our post or its meaning because of enabled html, and some mess in in the code. Basic example:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;for(var i = 0; i&amp;lt;length; ++i) ...&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Above snippet, extremely common, could cause unexpected problems due to the "i less than length" where the "&lt;" character create a never-ending tag.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;How can we solve the problem?&lt;/h3&gt;Usually I copy and paste code in a new document via CTRL+N inside Notepad++, and I replace every "&lt;" with &amp;amp;lt; ... but I have to admit: &lt;strong&gt;boring stuff&lt;/strong&gt;!!! I discovered yesterday in &lt;a href="http://www.dustindiaz.com/"&gt;Dustin Diaz blog&lt;/a&gt;, and I messed up completely a couple of comments, that there is a service, called &lt;a href="http://www.elliotswan.com/postable/"&gt;postable&lt;/a&gt;, "&lt;em&gt;to make your code friendly&lt;/em&gt;". First of all, I'll never get why that Ajax call exist, safetuze.php will never do anything different from an htmlentities or an htmlspecialchars but apparently I am wrong:&lt;ol&gt;&lt;br /&gt;    &lt;li&gt;plus signs disappears, probably the author send without the proper encodeURIComponent JavaScript function, &lt;strong&gt;annoying&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;there is no reason at all to send back the entire textarea, we deal with a field, we would expect to wait only for what we wrote in that field (AHAH way for a textarea?), &lt;strong&gt;annoying&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;why we have to wait a server side call, is an absolute mistery ... as a plus, I am experiencing an USB pen to surf the web, and every single byte costs, &lt;strong&gt;annoying&lt;/strong&gt;&lt;/li&gt;&lt;br /&gt;    &lt;li&gt;a basic page like that with just a call to the server and &lt;strong&gt;prototype plus scriptacolous&lt;/strong&gt; to do it? &lt;strong&gt;unacceptable&lt;/strong&gt;!!!&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;br /&gt;postable, in my opinion, is a "not that good answer" to a truly common problem ... so&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;again, how can we solve the problem?&lt;/h3&gt;I created a totally cross browser page, thinking about bandwidth, simplicity, and performances. So &lt;strong&gt;&lt;a href="http://www.3site.eu/encode/"&gt;here I am with en-code&lt;/a&gt;&lt;/strong&gt;, the same purpose of postable, except it just escape code snippets on client side (N times faster) and it does not require an entire framework to do a single thing.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;3KB Against 183KB&lt;/h3&gt; ... and only congrats via &lt;a href="http://websiteoptimization.com/services/analyze/"&gt;Web Page Analyzer&lt;/a&gt; ...&lt;br /&gt;Let me know what you think, enjoy ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-7081271171563878935?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/7081271171563878935/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=7081271171563878935" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/7081271171563878935" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/7081271171563878935" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/4tWGJbcDYd0/en-code-quickest-way-to-encode-your.html" title="en-code: the quickest way to encode your snippet" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">11</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/05/en-code-quickest-way-to-encode-your.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-6373867766954427119</id><published>2009-05-25T23:02:00.002+02:00</published><updated>2009-05-25T23:43:36.351+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Template" /><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="engine" /><category scheme="http://www.blogger.com/atom/ns#" term="XML" /><category scheme="http://www.blogger.com/atom/ns#" term="XSLT" /><title type="text">Template Engine - Why Bother? XML + XSLT</title><content type="html">I am not sure I read the entire recent "&lt;em&gt;war&lt;/em&gt;" in the PHP general mailing list about the best &lt;a href="http://marc.info/?l=php-general&amp;m=124311728404917&amp;w=2"&gt;PHP Template Engine Option&lt;/a&gt; but, generally speaking, this argument is truly loads of solutions and controversial opinions. Here I am with mine.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;PHP 5 And In Core DOM, XML and XSLT&lt;/h3&gt;Apparently, all these "&lt;em&gt;Smarty adorers&lt;/em&gt;" did not consider that PHP 5 introduced a lot of core classes to work over DOM, XML, and transform them via XSL files. Nothing to do, &lt;strong&gt;they prefer to move an entire template application rather than use the best native, fast, in core, solution&lt;/strong&gt;. Here a couple of reasons to generally prefer XML and XSL Transformations rather than whatever engine, specially those written in PHP itself, a &lt;em&gt;not that fast&lt;/em&gt; interpreted programming language.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Think Portable&lt;/h3&gt;Apparently &lt;em&gt;developers like to be stuck forever in a single programming language&lt;/em&gt;, something I cannot even try to consider, since &lt;strong&gt;Information Technology means Flexibility and Updates&lt;/strong&gt;. An extremely valid point to choose &lt;strong&gt;XML as output, and XSL as Transformer&lt;/strong&gt;, is the universality of the XML markup language first, and &lt;strong&gt;complete separation between data and business logic from its presentation&lt;/strong&gt; after.&lt;br /&gt;Something PHP developers often look for, discarding without a valid reason what is already there since ages. Even if the entire website or application programming language will change (performances anybody?), rather than simply take care about how to reproduce the same XML via the new language, they prefer to recreate for each sub-part of the website the code to make that completely new and different template engine work. This becomes even more ridiculous when arguments are like:&lt;blockquote&gt; if I need php in the middle of the presentation layer, I simply put it there ...&lt;br /&gt;&lt;/blockquote&gt; ... "&lt;em&gt;good thinking&lt;/em&gt;", isn't it?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Think Scalable&lt;/h3&gt;&lt;br /&gt;First of all, XML can be easily cached without even moving a single database connection. Moreover, having zero dependencies from external engines probably based on the same XML + XSLT concept, could simply make our application faster. XML has thousands of implementations, libraries, and fast parsers, for every kind of programming language and latest dabases could even interact directly with stored XML (or retrieve data directly in XML, did you know that?)&lt;br /&gt;An application that as main intermediate layer has XML will have so many long therms advantages hard to imagine, are you still thinking a foreach inside the layout is a good solution?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Think About Your Career&lt;/h3&gt;&lt;br /&gt;Ok, I use PHP and I want a template engine that will bring me nothing new to learn, except its own PHP exposed API. And tomorrow, when I'll move into another better structured company, everything about XML, XSL(T), and XPath, will be a non-sense, "&lt;em&gt;'cause I know peeaichpee&lt;/em&gt;", isn't it?&lt;br /&gt;If you think you know enough about XML and XSLT and you are not using these layers I bet you do not truly know them or real potentials.&lt;br /&gt;I bet you do not know XPath, you do not know how to generate a valid XHTML/HTML layout, and you do not know XSLT strategies to retrieve only info you want to show and nothing else.&lt;br /&gt;Well, think about this, more enterprise ready stuff, rather than just whoevercanuseit programming language (easy to start, hard to use properly, that's PHP) ... is it an extra plus to at least give them a try?&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Extreme Performances? A concrete Example&lt;/h3&gt;&lt;br /&gt;&lt;a href="http://www.nytimes.com/"&gt;The New York Times&lt;/a&gt; website is using these technologies since ages and it implemented its own &lt;a href="http://code.nytimes.com/projects/xslcache?scp=1&amp;sq=PHP%20XSL%20cache&amp;st=cse"&gt;XSL Cache Extension&lt;/a&gt; in order to obtain &lt;a href="http://code.nytimes.com/projects/xslcache/wiki/PerformanceBenchmarks?scp=3&amp;sq=PHP%20XSL%20cache&amp;st=cse"&gt;best performances&lt;/a&gt; with xsl documents. At the same time, &lt;strong&gt;XSLT is present in every browser, included Internet Explorer 5&lt;/strong&gt; so it is even possible to simply delegate transformation to the client, speeding up even more the server. Here &lt;a href="http://www.3site.eu/JXON/index.html"&gt;a simple example&lt;/a&gt;, based on my "old" &lt;a href="http://webreflection.blogspot.com/2008/07/jxon-lossless-javascript-to-xml-object.html"&gt;JXON&lt;/a&gt; proposal.&lt;br /&gt;&lt;br /&gt;Do you still think there are so many better options?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-6373867766954427119?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/6373867766954427119/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=6373867766954427119" title="16 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6373867766954427119" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6373867766954427119" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/sU9m7Y6TOPA/template-engine-why-bother-xml-xslt.html" title="Template Engine - Why Bother? XML + XSLT" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">16</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/05/template-engine-why-bother-xml-xslt.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-6600550617059278777</id><published>2009-05-24T13:13:00.005+02:00</published><updated>2009-05-24T13:24:22.081+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Application" /><category scheme="http://www.blogger.com/atom/ns#" term="Ajax" /><category scheme="http://www.blogger.com/atom/ns#" term="Twitter" /><title type="text">Basic Ajax Twitter Application</title><content type="html">Yesterday I posted a work in progress of a &lt;a href="http://webreflection.blogspot.com/2009/05/php-full-proxy-work-in-progress.html"&gt;Full PHP Ajax Proxy&lt;/a&gt;, today I would like to show you what you could do with that file.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Twitter API Directly via Ajax&lt;/h3&gt;&lt;br /&gt;Thanks to basic realm authentication support, it is extremely simple to create your own twitter app in your home page. Here the example:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;&amp;lt;style type="text/css"&amp;gt;&lt;br /&gt;div.twit {&lt;br /&gt;    font-family: "Lucida Grande", "Lucida Sans Unicode", "Lucida Sans", Verdana, Tahoma, sans-serif;&lt;br /&gt;    width: 320px;&lt;br /&gt;}&lt;br /&gt;div.twit h3,&lt;br /&gt;div.twit h4 {&lt;br /&gt;    margin: 0;&lt;br /&gt;    padding: 0;&lt;br /&gt;}&lt;br /&gt;div.twit h3 {&lt;br /&gt;    font-size: 10pt;&lt;br /&gt;    color: blue;&lt;br /&gt;}&lt;br /&gt;div.twit h4 {&lt;br /&gt;    font-size: 7pt;&lt;br /&gt;    font-weight: normal;&lt;br /&gt;    text-align: right;&lt;br /&gt;    color: #999;&lt;br /&gt;}&lt;br /&gt;div.twit span {&lt;br /&gt;    font-size: 8pt;&lt;br /&gt;}&lt;br /&gt;&amp;lt;/style&amp;gt;&lt;br /&gt;&amp;lt;script type="text/javascript" src="http://vice-versa.googlecode.com/svn/trunk/build/vice-versa.min.js"&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;&lt;br /&gt;function addIntoList(info, container){&lt;br /&gt;    var div = document.createElement('&amp;lt;div class="twit"&amp;gt;&amp;lt;/div&amp;gt;'),&lt;br /&gt;        h3  = div.appendChild(document.createElement("h3")),&lt;br /&gt;        span= div.appendChild(document.createElement("span")),&lt;br /&gt;        h4  = div.appendChild(document.createElement("h4"))&lt;br /&gt;    ;&lt;br /&gt;    h3.innerText = info.user.screen_name;&lt;br /&gt;    h4.innerText = info.created_at.substring(0, 19);&lt;br /&gt;    span.innerHTML = info.text.replace(/([a-zA-Z]+:\/\/[^\s]+)/g, '&amp;lt;a href="$1"&amp;gt;$1&amp;lt;/a&amp;gt;');&lt;br /&gt;    container.insertBefore(div, container.firstChild);&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;onload = function(){&lt;br /&gt;    var xhr = new XMLHttpRequest;&lt;br /&gt;    xhr.open(&lt;br /&gt;        "GET", "proxy.php?url=" +&lt;br /&gt;        "http://twitter.com/statuses/friends_timeline.json" + "?_=" + Math.random(),&lt;br /&gt;        false,&lt;br /&gt;        "YOURNAME",&lt;br /&gt;        "YOURPASS"&lt;br /&gt;    );&lt;br /&gt;    xhr.send(null);&lt;br /&gt;    if(199 &amp;lt; xhr.status &amp;&amp; xhr.status &amp;lt; 400){&lt;br /&gt;        document.body.innerHTML = "";&lt;br /&gt;        for(var&lt;br /&gt;            list = Function("return " + xhr.responseText)().reverse(),&lt;br /&gt;            length = list.length,&lt;br /&gt;            i = 0;&lt;br /&gt;            i &amp;lt; length; ++i&lt;br /&gt;        )&lt;br /&gt;            addIntoList(list[i], document.body);&lt;br /&gt;    };&lt;br /&gt;    setTimeout(onload, 10000); // again after 10 seconds&lt;br /&gt;};&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Be Careful!!!&lt;/h3&gt;&lt;br /&gt;First of all it is not a good idea to put user and password directly in your page source code, so try locally but do not put online. Secondly, I did not say anything yet about &lt;strong&gt;side effects and security problems&lt;/strong&gt; related to this PHP proxy I am working on ....so, as I wrote in the other post source, "&lt;em&gt;do not try at home&lt;/em&gt;"&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-6600550617059278777?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/6600550617059278777/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=6600550617059278777" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6600550617059278777" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6600550617059278777" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/Q7C2t_98c6s/basic-ajax-twitter-application.html" title="Basic Ajax Twitter Application" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/05/basic-ajax-twitter-application.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-6151019560453692001</id><published>2009-05-24T00:44:00.006+02:00</published><updated>2009-07-13T18:27:23.610+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="PHP" /><category scheme="http://www.blogger.com/atom/ns#" term="XMLHttpRequest" /><category scheme="http://www.blogger.com/atom/ns#" term="Ajax" /><category scheme="http://www.blogger.com/atom/ns#" term="proxy" /><title type="text">PHP Full Proxy ... A Work In Progress</title><content type="html">Something "&lt;em&gt;truly dangerous&lt;/em&gt;" to play with: a proxy file able to understand everything via XMLHttpRequest, enabling any sort of cross site requests (no COMET yet, it could arrive soon).&lt;br /&gt;Dunno even why I am posting this "&lt;em&gt;little monster&lt;/em&gt;", but I am sure a lot of people would like to have "&lt;em&gt;access to the entire web&lt;/em&gt;" simply using Ajax, and nothing else, something like this:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;function website_exists(url){&lt;br /&gt;    var xhr = new XMLHttpRequest;&lt;br /&gt;    xhr.open("HEAD", "proxy.php?url=" + (url), false);&lt;br /&gt;    xhr.send(null);&lt;br /&gt;    return 199 &lt; xhr.status &amp;&amp; xhr.status &lt; 400;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;if(website_exists("http://gogle.com"))&lt;br /&gt;    alert("Of Course, It's Big G!");&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;WebReflection PHP Proxy&lt;/h3&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;&amp;lt;?php&lt;br /&gt;&lt;br /&gt;/** XMLHttpRequest PHP Proxy&lt;br /&gt; * @author          Andrea Giammarchi&lt;br /&gt; * @blog            http://webreflection.blogspot.com/&lt;br /&gt; * @license         Mit Style License&lt;br /&gt; * @requires        curl and Apache webserver&lt;br /&gt; * @description     basic authentication, GET, POST, HEAD, PUT, DELETE, others requests types.&lt;br /&gt; *                  Nothing to do on the client side, except put "proxy.php?url=" as request prefix.&lt;br /&gt; *                  The rest should be like normal in-server interaction&lt;br /&gt; * @note            DON'T TRY AT HOME&lt;br /&gt; */&lt;br /&gt;&lt;br /&gt;// if no url has been provided, exit&lt;br /&gt;if(!isset($_GET['url'])){&lt;br /&gt;    header('HTTP/1.1 400 Bad Request');&lt;br /&gt;    header('X-Proxy-Error: no url');&lt;br /&gt;    exit;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// work in progress&lt;br /&gt;/* without Apache ... requires alternatives for Authorization and other stuff not in $_SERVER&lt;br /&gt;if(!function_exists('getallheaders')){&lt;br /&gt;    function getallheaders(){&lt;br /&gt;        $headers= array();&lt;br /&gt;        foreach($_SERVER as $key =&amp;gt; $value){&lt;br /&gt;            if(0 === strpos($key, 'HTTP_'))&lt;br /&gt;                $headers[str_replace(' ', '-', ucwords(str_replace('_', ' ', strtolower(substr($key, 5)))))] = $value;&lt;br /&gt;        }&lt;br /&gt;        return $headers;&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;// */&lt;br /&gt;&lt;br /&gt;// GET, POST, PUT, HEAD, DELETE, ect ...&lt;br /&gt;$method = $_SERVER['REQUEST_METHOD'];&lt;br /&gt;&lt;br /&gt;// curl headers array&lt;br /&gt;$headers= array();&lt;br /&gt;foreach(getallheaders() as $key =&amp;gt; $value)&lt;br /&gt;    $headers[] = $key.': '.$value;&lt;br /&gt;&lt;br /&gt;// curl options&lt;br /&gt;$opts   = array(&lt;br /&gt;    CURLOPT_HEADER =&amp;gt; true,&lt;br /&gt;    CURLOPT_RETURNTRANSFER =&amp;gt; true,&lt;br /&gt;    CURLOPT_BINARYTRANSFER =&amp;gt; true,&lt;br /&gt;    CURLOPT_CUSTOMREQUEST =&amp;gt; $method,&lt;br /&gt;    CURLOPT_HTTPHEADER =&amp;gt; $headers&lt;br /&gt;);&lt;br /&gt;&lt;br /&gt;// if request is post ...&lt;br /&gt;if($method === 'POST'){&lt;br /&gt;    // populate the array of keys/values to send&lt;br /&gt;    $headers = array();&lt;br /&gt;    foreach($_POST as $key =&amp;gt; $value)&lt;br /&gt;        $headers[] = rawurlencode($key).'='.rawurlencode($value);&lt;br /&gt;    $opts[CURLOPT_POST] = true;&lt;br /&gt;    $opts[CURLOPT_POSTFIELDS] = implode('&amp;', $headers);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// if it is a basic authorization request ...&lt;br /&gt;if(isset($_SERVER['PHP_AUTH_USER'], $_SERVER['PHP_AUTH_PW'])){&lt;br /&gt;    // create user and pass parameters to send&lt;br /&gt;    $opts[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC;&lt;br /&gt;    $opts[CURLOPT_PROXYUSERPWD] = '['.&lt;br /&gt;        rawurlencode($_SERVER['PHP_AUTH_USER'])&lt;br /&gt;    .']:['.&lt;br /&gt;        rawurlencode($_SERVER['PHP_AUTH_PW'])&lt;br /&gt;    .']'&lt;br /&gt;    ;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// init curl session&lt;br /&gt;$call   = $session = curl_init(substr($_SERVER['QUERY_STRING'], 4));&lt;br /&gt;&lt;br /&gt;// set all options&lt;br /&gt;curl_setopt_array($call, $opts);&lt;br /&gt;&lt;br /&gt;// clear unnecessary variables&lt;br /&gt;unset($opts);&lt;br /&gt;unset($headers);&lt;br /&gt;&lt;br /&gt;// retrieve the output&lt;br /&gt;$result = explode(PHP_EOL, curl_exec($call));&lt;br /&gt;&lt;br /&gt;// nothing else to do so far (this version is not compatible with COMET)&lt;br /&gt;curl_close($call);&lt;br /&gt;&lt;br /&gt;// for each returned information ...&lt;br /&gt;for($i = 0, $length = count($result), $sent = array(); $i &amp;lt; $length; ++$i){&lt;br /&gt;    $value = $result[$i];&lt;br /&gt;    &lt;br /&gt;    // if all headers has been sent ...&lt;br /&gt;    if($value === '')&lt;br /&gt;        // send the output&lt;br /&gt;        exit(implode(PHP_EOL, array_splice($result, ++$i)));&lt;br /&gt;    else {&lt;br /&gt;        // ... or send the header (do not overwrite if already sent)&lt;br /&gt;        $tmp = explode(':', $value);&lt;br /&gt;        header($value, !isset($sent[strtolower($tmp[0])]));&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;?&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Have fun exploring the net ;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-6151019560453692001?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/6151019560453692001/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=6151019560453692001" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6151019560453692001" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/6151019560453692001" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/OPdYLfvXyK8/php-full-proxy-work-in-progress.html" title="PHP Full Proxy ... A Work In Progress" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/05/php-full-proxy-work-in-progress.html</feedburner:origLink></entry><entry><id>tag:blogger.com,1999:blog-34454975.post-3451657859903089616</id><published>2009-05-23T15:15:00.004+02:00</published><updated>2009-05-23T15:55:30.089+02:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="Internet Explorer" /><category scheme="http://www.blogger.com/atom/ns#" term="arguments" /><category scheme="http://www.blogger.com/atom/ns#" term="mode" /><category scheme="http://www.blogger.com/atom/ns#" term="conflicts" /><category scheme="http://www.blogger.com/atom/ns#" term="ECMAScript 5" /><category scheme="http://www.blogger.com/atom/ns#" term="callee" /><category scheme="http://www.blogger.com/atom/ns#" term="Strict" /><title type="text">[ECMAScript 5] Do Not Remove arguments.callee !</title><content type="html">Being subscribed in dunno how many developers mailing list, I completely forgot to follow up the arguments and arguments.callee discussion.&lt;br /&gt;Accordingly to &lt;a href="http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/"&gt;this John post&lt;/a&gt;, is with extreme surprise that I am discovering how critical is the gap between programming language developers and programming languages active users.&lt;br /&gt;&lt;br /&gt;Even if I read more than once piece of SpiderMonkey or Google Chrome, I am part of programming languages users and I can tell you for sure that the decision to remove arguments.callee from the language will be a complete mess.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;The Main Aim Of ECMAScript 5: Do Not Break What We Have So Far&lt;/h3&gt;Unfortunately, &lt;strong&gt;Internet Explorer will be broken&lt;/strong&gt;, because &lt;strong&gt;named function persists in the scope&lt;/strong&gt;, causing &lt;strong&gt;naming conflicts everywhere&lt;/strong&gt;!&lt;br /&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;setTimeout(function f(){&lt;br /&gt;    alert(window.f);&lt;br /&gt;}, 1000);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Above code will alert the function f in &lt;strong&gt;every Internet Explorer&lt;/strong&gt;. Moreover, as you can read in one comme of John's entry, &lt;a href="http://nedbatchelder.com/blog/200812/internet_explorer_mystery_1376.html"&gt;Internet Explorer has function interpretation "problems"&lt;/a&gt;, declaring or overriding already declared function even if these are in an &lt;em&gt;else case&lt;/em&gt;, while other browsers do not even consider that part of code if it will never be executed.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Another Attemp To Slow Down The Already Slow Browser&lt;/h3&gt;&lt;br /&gt;Reading &lt;a href="https://mail.mozilla.org/pipermail/es-discuss/2009-March/008970.html"&gt;this long thread&lt;/a&gt; about the discussion, some clever guy suggested a simple solution to avoid naming conflicts ... &lt;strong&gt;a closure&lt;/strong&gt;&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;(function(){&lt;br /&gt;    setTimeout(function f(){&lt;br /&gt;        alert(window.f);&lt;br /&gt;    }, 1000);&lt;br /&gt;})();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;This simply means that our code size &lt;strong&gt;will drastically increase&lt;/strong&gt; without a valid reason and &lt;strong&gt;number of created scopes and functions will be twice&lt;/strong&gt; as was before (already too big). They think it will not slow down performances but they are forgetting old browsers that will be still used when all this wonderful shiny JavaScript will be released: Internet Explorer 7, and Internet Explorer 8 (assuming Internet Explorer 6 does not exist anymore ... would be nice to start to fight against the version 7 and then 8 ...).&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Introspection and BackTrace? They Decided It Is A Bad Thing!&lt;/h3&gt;&lt;br /&gt;Without arguments.callee we are loosing arguments.callee.caller as well, often the only way we have to truly debug our code. At the same time the dynamic nature of JavaScript where "&lt;em&gt;you can inject whatever wherever&lt;/em&gt;" will loose a big portion of its malleability.&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Everything For Performances Reason ???&lt;/h3&gt;&lt;br /&gt;Apparently what &lt;strong&gt;this "new" language would like to get rid off&lt;/strong&gt; is &lt;strong&gt;arguments variable&lt;/strong&gt;, probably the most used variable ever, the inspiration of every ArrayLike object or library. This would be for performances, where we need as first step to call 2 functions rather than one for each runtime function assignment (setTimeout example and every assigned inline lambda) and where everybody will try to overload the language itself providing other methods to emulate the good old stuff!&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;Let's Start To Think About Re-Implementation Of Callee&lt;/h3&gt;As soon as I realized the news, I decided to think how to put again, and against performances, the callee behavior.&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt; function F(original){&lt;br /&gt;    return function(){&lt;br /&gt;        var f = window.callee,&lt;br /&gt;            r = (callee = original).apply(this, arguments)&lt;br /&gt;        ;&lt;br /&gt;        window.callee = f;&lt;br /&gt;        return r;&lt;br /&gt;    };&lt;br /&gt;}; &lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Above snippet execution time will be almost the same of a closure with mainly two advantages&lt;ul&gt;&lt;br /&gt;&lt;li&gt;less code to write&lt;/li&gt;&lt;br /&gt;&lt;li&gt;more performances when needed&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;Here an example:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;var i = 0;&lt;br /&gt;setTimeout(F(function(){&lt;br /&gt;    if(i++ === 1)&lt;br /&gt;        alert("OK");&lt;br /&gt;    else&lt;br /&gt;        setTimeout(callee /* please read more */, 1000);&lt;br /&gt;}), 1000);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Since JavaScript is single thread, the instant that lambda will be called the global variable callee will refer to the lambda itself. Cool, but it is not enough.&lt;br /&gt;To be sure that we do not loose the callee because of some other function assignment, we should trap again the callee inside that execution:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;var i = 0;&lt;br /&gt;setTimeout(F(function(){&lt;br /&gt;    if(i++ === 1)&lt;br /&gt;        alert("OK");&lt;br /&gt;    else&lt;br /&gt;        setTimeout(F(callee), 1000);&lt;br /&gt;}), 1000);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;There we are, a quick and dirty solution to the problem ... &lt;strong&gt;but&lt;/strong&gt;, in this case for each timeout we are creating another function within its scope. This does not happen if we use the closure strategy so, again, we are trapped and we need to add more layers in the middle to increase responsiveness for something designed to improve performances ... does it make any sense?&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;function F(original){&lt;br /&gt;    function callee(){&lt;br /&gt;        // save the current window.callee&lt;br /&gt;        var f = window.callee, r;&lt;br /&gt;        // assign this callee function&lt;br /&gt;        window.callee = callee;&lt;br /&gt;        // retrieve the result calling original&lt;br /&gt;        // in the original scope, callee will be&lt;br /&gt;        // this whole function&lt;br /&gt;        r = original.apply(this, arguments);&lt;br /&gt;        // assign back the window callee&lt;br /&gt;        window.callee = f;&lt;br /&gt;        // return the result&lt;br /&gt;        return r;&lt;br /&gt;    };&lt;br /&gt;    // callee.callee will be the lambda&lt;br /&gt;    // rather than its wrap (callee itself)&lt;br /&gt;    callee.callee = original;&lt;br /&gt;    // here we are&lt;br /&gt;    return callee;&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;With above "monster" we have a slightly slower function that will always reassign the correct callee whatever will happen in the original function scope. This meanse simply that we can now use directly callee:&lt;br /&gt;&lt;pre class="code"&gt;&lt;br /&gt;var i = 0;&lt;br /&gt;setTimeout(F(function(){&lt;br /&gt;    if(i++ === 1)&lt;br /&gt;        alert("OK");&lt;br /&gt;    else&lt;br /&gt;        setTimeout(callee, 1000);&lt;br /&gt;    // callee.callee for direct access to the lambda itself&lt;br /&gt;}), 1000);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h3&gt;I Bloody Hate This Idea&lt;/h3&gt; ... but if they do not change their mind, it will be one of few other possibilities we have to avoid naming pollution everywhere causing conflicts nightmare with every Internet Explorer version less than 9.&lt;br /&gt;&lt;br /&gt;Have fun with ECMAScript 5 and its brilliant strict mode.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/34454975-3451657859903089616?l=webreflection.blogspot.com'/&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://webreflection.blogspot.com/feeds/3451657859903089616/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=34454975&amp;postID=3451657859903089616" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/3451657859903089616" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/34454975/posts/default/3451657859903089616" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/WebReflection/~3/x_KBMzXfojs/ecmascript-5-do-not-remove.html" title="[ECMAScript 5] Do Not Remove arguments.callee !" /><author><name>Andrea Giammarchi</name><uri>http://www.blogger.com/profile/16277820774810688474</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd="http://schemas.google.com/g/2005" name="OpenSocialUserId" value="11324065305198565288" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://webreflection.blogspot.com/2009/05/ecmascript-5-do-not-remove.html</feedburner:origLink></entry></feed>
