I have enclosed in only 5 steps JScript weirdness, hoping all precedent deliriums about functions, standards, and Internet Explorer, will make more sense now.
Here there is the link to original HTML slides, I hope this will help everybody to have clearer ideas.
behind the design
My JavaScript book is out!
Don't miss the opportunity to upgrade your beginner or average dev skills.
Showing posts with label Internet Explorer. Show all posts
Showing posts with label Internet Explorer. Show all posts
Tuesday, October 13, 2009
Friday, August 14, 2009
Defeat Internet Explorer - Can You?
While I was creating a stand alone implementation of the LSSP described in my last HTML5 sessionStorage project, I did some test and bench as every Agile developer should do.
Well, what I have discovered, is that apparently Internet Explorer could perform some common task better than any other browser, at least in my good old Intel Centrino 1.6 Ghz.
I have created a benchmark page able to freeze my Firefox 3.5.2, to ask me if I would like to continue an Array.join execution with an average score that points out my Internet Explorer 8 wins with a score under 300 milliseconds against Chrome, Firefox and Safari.
As summary, is my Centrino dead or there's something we all did not consider about JScript engine?
P.S. Opera 10 beta 2 seems to score about 130 milliseconds as average, good stuff!
Well, what I have discovered, is that apparently Internet Explorer could perform some common task better than any other browser, at least in my good old Intel Centrino 1.6 Ghz.
I have created a benchmark page able to freeze my Firefox 3.5.2, to ask me if I would like to continue an Array.join execution with an average score that points out my Internet Explorer 8 wins with a score under 300 milliseconds against Chrome, Firefox and Safari.
As summary, is my Centrino dead or there's something we all did not consider about JScript engine?
P.S. Opera 10 beta 2 seems to score about 130 milliseconds as average, good stuff!
Wednesday, June 17, 2009
The One With Microsoft Paying Users
You probably do not know what's happened today at about UTC lunch time. It has been just a quick twit from John Resig, that at least every follower instantly noticed the next Microsoft campaign pro Internet Explorer 8.
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.
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!
Which part is tarnished? Google is a "neverendingmoving" 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).
The Fact
Microsoft Australia launched a sort of "competition", called Ten Grand. 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").The Problem
That Web Page literally insults other web browsers, even discarding, probably on purpose, Opera one. In few words, that game is only for Internet Explorer 8 Users. 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?- You'll never find it using old Firefox
- You'll never find it using boring Safari
- You'll never find it using tarnished Chrome
The Old Firefox
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!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.
The Boring Safari
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 kiddish gne, gne, gne 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 WebKit 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!The Tarnished Chrome
... wait a second, it's probably me .... let me think ... "tarnished Chrome ... rome ... ome ... om". 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?)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!
Which part is tarnished? Google is a "neverendingmoving" 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).
The Smell Of 90s Competition Page
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, what the hell is that, 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 able to emulate IE8 without receiving insults. 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?Wednesday, June 10, 2009
ExtJS And The Bloody TreePanel Arrow
First of all I am sorry for choose title, but I kinda lost dunno how many minutes to figure out what was wrong, and it was not me!
Please let me try to explain what was the requirement, and how I had to force ExtJS to act as I want, version 2.2.1 or 3.0RC2, it does not matter.
As example, try to click Start and Run a prompt command, explorer.
This is the typical Window$ file browser, something we deal with since ages, something still a user habit.
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? It's NOT, unless I am missing an hidden part of ExtJS documentation because I swear I tried everything.
That's it, waiting for comments, better examples, or even solution I could not think about!
Please let me try to explain what was the requirement, and how I had to force ExtJS to act as I want, version 2.2.1 or 3.0RC2, it does not matter.
The Problem ...
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 6. 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.As example, try to click Start and Run a prompt command, explorer.
This is the typical Window$ file browser, something we deal with since ages, something still a user habit.
... In Details
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 only if we click a folder. That is the problem, the Jurassic explorer acts differently if we click the [+] rather than the folder/file. 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.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? It's NOT, unless I am missing an hidden part of ExtJS documentation because I swear I tried everything.
Ext.tree.TreePanel Hacked To Have More Control Over The Arrow
... 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 tdginnovations asked me, via twitter, to make this problem public, with solution as well.
// good old onload ...
onload = function(){
// simple function to add nodes
// just for this example
function addNodes(root, dummyData){
for(var
i = 0, length = dummyData.length,
cls = {true:"file",false:"folder"},
data, leaf;
i < length; ++i
){
data = dummyData[i];
leaf = root.appendChild(new Ext.tree.TreeNode({
text:data.text,
leaf:!data.items,
cls:cls[!data.items]
}));
if(data.items)
addNodes(leaf, data.items);
};
};
var
// just a sync example
// with a couple of folders
dummyData = [
{text:"Test 1", items:[
{text:"Sub Test 1 1"},
{text:"Sub Test 1 2"}
]},
{text:"Test 2"},
{text:"Test 3", items:[
{text:"Sub Test 3 1"},
{text:"Sub Test 3 2", items:[
{text:"Sub Test 3 2 1"},
{text:"Sub Test 3 2 2"}
]},
{text:"Sub Test 3 3"}
]}
],
// the lovely TreePanel
TreePanel = new Ext.tree.TreePanel({
renderTo:document.body,
border:false,
rootVisible: false,
root:{
expanded: true,
text: "",
draggable: false
},
// global TreePanel events
listeners:{
// Hack #1: The Lovely Arrow ..
// here starts the open hack ...
// when the arrow is clicked,
// no click event is propagated
// but when the node is clicked
// beforeexpandnode is called ...
// to avoid troubles I used a flag
// in order to discard next
// beforeexpandnode event
// without returning false
// but if this is the arrow
// without the click ... so
// the lonely beforeexpandnode ...
beforeexpandnode:function(Node){
// check if the flag is not setted
if(!Node.beforeexpandnode){
// set the flag, prevent
// return false onclick event
Node.beforeexpandnode = true;
// fire the click event
// the one in charge
// to load or show stuff
Node.fireEvent("click", Node);
// block this call
// or we gonna open twice ...
// with possible loops
// (at least in Ext 2.2.1)
return false;
}
},
// here we are ...
// if it was a click in the name/folder/leaf
// this event is fired before beforeexpandnode
// we need to check a couple of things ...
click:function(Node, e){
// if node is expanded
// we do not need to do anything
if(Node.isExpanded()){
console.log("already expanded");
}
// but if node is not expanded
// and the beforeexpandnode flag
// has been setted as true ...
else if(Node.beforeexpandnode) {
// we know that this click
// is from the arrow, and not
// from the folder or name
console.log("expand via arrow/plus or minus");
// we can load stuff async, putting
// a mask to the panel before, removing it
// on load success, add nodes
// and finally expand this Node
// this if should not exists if
// the node is a leaf, cause there
// is no arrow beside
Node.expand();
}
// if node is not expanded but it is
// a folder and beforeexpandnode flag
// has not been setted as true
// we know that the user performed
// a click ...
else if(!Node.isLeaf()) {
// to avoid another click event
// triggered via beforeexpandnode event
// we need to set the flag as true
// so beforeexpandnode will not
// return false calling this event
// again (precedent if)
Node.beforeexpandnode = true;
// at this point we could perform
// a different request
// which could return the entire node
// list plus some other information
// or simply do something else
// rather than just populate the
// Node with sub-nodes
console.log("expand via click");
// in this case, let's expand the node
Node.expand();
}
// none of precedent condition
// was true, interesting ...
// ... it must be just a leaf ;)
else {
// let's do something
// with this leaf
console.log(Node.text);
};
// the main problem with click
// is that it is not possible
// to avoid a double click
// e.stopEvent() ? no way
// it does not do anything with
// dblclick, useless
},
// last part of this little hack ...
// once the node is expanded
// it makes sense to
// set the flag as false
// so next beforeexpandnode event
// will work as expected
expandnode:function(Node){
Node.beforeexpandnode = false;
},
// Hack #2: ... I said:
// DO NOT CLOSE ON DOUBLE CLICK!!!
// at least this hack is even shorter
// but it still requires 2 events
// dblclick, as I said, cannot be
// stopped ... but it does not
// really matter, cause
// beforecollapsenode will be fired
// always before ... so, even
// implementing a proper stopEvent
// how could we avoid closing action
// from beforecollapsenode event
// since this is fired before
// dblclick?
// dblclick has to be a sort
// of filter able to change
// another flag
// beforecollapsenode
// if node is expanded
// we set the flag as false
// why ? ... read next ...
dblclick:function(Node, e){
if(Node.isExpanded())
Node.beforecollapsenode = false;
},
// beforecollapsenode event
// is fired before dblclick
// so this hack is about milliseconds.
// if the flag is not set
// we set it as true and we call a timetout
// Hopefully, the double click will be performed
// before choose timeout.
// If this happens, it means
// that the user double clicked the
// opened node, otherwise
// it means that the user did not
// mean a double click (the arrow
// does NOT fire a dblclick in any case)
// while He/She simpl clicked once in
// the arrow (or more than once to close it)
beforecollapsenode:function(Node){
if(!Node.beforecollapsenode){
Node.beforecollapsenode = true;
setTimeout(function(){
// so here this hack should
// perform its action ...
if(Node.beforecollapsenode)
// closing the node
// if it was not a dblclick
Node.collapse();
}, 20);
return false;
}
},
// to complete the task
// let's reset status
// on node collapsed
collapsenode:function(Node){
Node.beforecollapsenode = false;
}
}
})
;
// it's time to test
addNodes(TreePanel.getRootNode(), dummyData);
// and play with this version
TreePanel.render();
};
That's it, waiting for comments, better examples, or even solution I could not think about!
Saturday, May 23, 2009
[ECMAScript 5] Do Not Remove arguments.callee !
Being subscribed in dunno how many developers mailing list, I completely forgot to follow up the arguments and arguments.callee discussion.
Accordingly to this John post, is with extreme surprise that I am discovering how critical is the gap between programming language developers and programming languages active users.
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.
Above code will alert the function f in every Internet Explorer. Moreover, as you can read in one comme of John's entry, Internet Explorer has function interpretation "problems", declaring or overriding already declared function even if these are in an else case, while other browsers do not even consider that part of code if it will never be executed.
Reading this long thread about the discussion, some clever guy suggested a simple solution to avoid naming conflicts ... a closure
This simply means that our code size will drastically increase without a valid reason and number of created scopes and functions will be twice 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 ...).
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 "you can inject whatever wherever" will loose a big portion of its malleability.
Apparently what this "new" language would like to get rid off is arguments variable, 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!
Above snippet execution time will be almost the same of a closure with mainly two advantages
Here an example:
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.
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:
There we are, a quick and dirty solution to the problem ... but, 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?
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:
Have fun with ECMAScript 5 and its brilliant strict mode.
Accordingly to this John post, is with extreme surprise that I am discovering how critical is the gap between programming language developers and programming languages active users.
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.
The Main Aim Of ECMAScript 5: Do Not Break What We Have So Far
Unfortunately, Internet Explorer will be broken, because named function persists in the scope, causing naming conflicts everywhere!
setTimeout(function f(){
alert(window.f);
}, 1000);
Above code will alert the function f in every Internet Explorer. Moreover, as you can read in one comme of John's entry, Internet Explorer has function interpretation "problems", declaring or overriding already declared function even if these are in an else case, while other browsers do not even consider that part of code if it will never be executed.
Another Attemp To Slow Down The Already Slow Browser
Reading this long thread about the discussion, some clever guy suggested a simple solution to avoid naming conflicts ... a closure
(function(){
setTimeout(function f(){
alert(window.f);
}, 1000);
})();
This simply means that our code size will drastically increase without a valid reason and number of created scopes and functions will be twice 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 ...).
Introspection and BackTrace? They Decided It Is A Bad Thing!
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 "you can inject whatever wherever" will loose a big portion of its malleability.
Everything For Performances Reason ???
Apparently what this "new" language would like to get rid off is arguments variable, 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!
Let's Start To Think About Re-Implementation Of Callee
As soon as I realized the news, I decided to think how to put again, and against performances, the callee behavior.
function F(original){
return function(){
var f = window.callee,
r = (callee = original).apply(this, arguments)
;
window.callee = f;
return r;
};
};
Above snippet execution time will be almost the same of a closure with mainly two advantages
- less code to write
- more performances when needed
Here an example:
var i = 0;
setTimeout(F(function(){
if(i++ === 1)
alert("OK");
else
setTimeout(callee /* please read more */, 1000);
}), 1000);
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.
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:
var i = 0;
setTimeout(F(function(){
if(i++ === 1)
alert("OK");
else
setTimeout(F(callee), 1000);
}), 1000);
There we are, a quick and dirty solution to the problem ... but, 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?
function F(original){
function callee(){
// save the current window.callee
var f = window.callee, r;
// assign this callee function
window.callee = callee;
// retrieve the result calling original
// in the original scope, callee will be
// this whole function
r = original.apply(this, arguments);
// assign back the window callee
window.callee = f;
// return the result
return r;
};
// callee.callee will be the lambda
// rather than its wrap (callee itself)
callee.callee = original;
// here we are
return callee;
};
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:
var i = 0;
setTimeout(F(function(){
if(i++ === 1)
alert("OK");
else
setTimeout(callee, 1000);
// callee.callee for direct access to the lambda itself
}), 1000);
I Bloody Hate This Idea
... 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.Have fun with ECMAScript 5 and its brilliant strict mode.
Wednesday, April 22, 2009
Internet Explorer with V8 Engine :: A Partial Reality
Update now it works with Internet Explorer 7 and 8 with O3D plug-in enabled.
Today, via ajaxian, I discovered the new Google O3D project and as a nerd first, and a developer after, I instantly read the API.
Few seconds and I spot this: Use the V8 engine
OK, OK, whatever code you read there will not instantly work ... you have to understand the library and how to retrieve the dreamed eval function to make JavaScript execution possible inside the extremely fast V8 engine.
Obviously V8 integration is great with FireFox and other browsers, but a bit different in Internet Explorer.
This limitation is about the DOM manipulation, something that would make IE a good browser, but everything else, executed via V8 engine and without browser engine references, will perform 5 to 100 time faster.
Function creations, optimized loops, numbers, string manupulation, etc etc ... if we could use a little plugin to fully integrate V8 inside Explorer, we could all forget nowadays benchmark because it will perform better than many other browsers!
Bearing in mind the relationship between V8 variables, different 100% from JScript vars, and latter variables, we can delegate computational tasks to this engine makin IE fast as it has never (and will probably never) been!
What I have so far, is just a poor example about V8 inside IE possibilities, a page that does not work if you do not have V8 inside Exlorer and you do not enable its usage everywhere.
Write a loop like this in the textarea:
and switching between default and V8 you can read that the difference is about 5 times slower with the default Internet Explorer JavaScript engine, and Google V8.
Still, so far what I can spot as pros and cons is this:
Pros
Cons
This was just a quick post and an experiment which in my opinion is already god enough. I have a vision, about Internet Explorer 8.1 ... those guys created an April fool that is everything but not a fool. Come on Microsoft, let others replace your old, problematic, slow, JScript engine, and let us developers be free to create Web Applications as we would like to do ... please give to Google whatever they need to make V8 IE integartion possible, and let us dream about a not that far possible Web future!
Today, via ajaxian, I discovered the new Google O3D project and as a nerd first, and a developer after, I instantly read the API.
Few seconds and I spot this: Use the V8 engine
OK, OK, whatever code you read there will not instantly work ... you have to understand the library and how to retrieve the dreamed eval function to make JavaScript execution possible inside the extremely fast V8 engine.
Obviously V8 integration is great with FireFox and other browsers, but a bit different in Internet Explorer.
This limitation is about the DOM manipulation, something that would make IE a good browser, but everything else, executed via V8 engine and without browser engine references, will perform 5 to 100 time faster.
Function creations, optimized loops, numbers, string manupulation, etc etc ... if we could use a little plugin to fully integrate V8 inside Explorer, we could all forget nowadays benchmark because it will perform better than many other browsers!
Bearing in mind the relationship between V8 variables, different 100% from JScript vars, and latter variables, we can delegate computational tasks to this engine makin IE fast as it has never (and will probably never) been!
What I have so far, is just a poor example about V8 inside IE possibilities, a page that does not work if you do not have V8 inside Exlorer and you do not enable its usage everywhere.
Write a loop like this in the textarea:
for(var a = [], i = 0; i < 500000; ++i)
a[i] = Math.random();
and switching between default and V8 you can read that the difference is about 5 times slower with the default Internet Explorer JavaScript engine, and Google V8.
Still, so far what I can spot as pros and cons is this:
Pros
- mathematical operations up to 100 times faster
- computational functions speed up
- common AI patterns (AStar) finally usable in the web
- games, chess, cards, whatever involves logic, speed up
Cons
- even if you assign a V8 Array.prototype.forEach to native Array.prototype.forEach, the plugin cannot solve engine related dependencies problems ... so it will be simply slower, much slower, because of the data interchange between the method executed externally, and the original engine
- DOM is not integrated, V8 in IE does not understand nodes so no way to speed up common libraries or add prototypes to native HTMLElement constructor
- last, but not least, with my laptop I cannot even test the example page I posted before because the JS is not that perfect (Google guys, makeClients accept an id but you check .id === "o3d" in the loop ... does it make any sense?) and my card apparently does not support OpenGL or whatever library the o3d plugin requires
As Summary
This was just a quick post and an experiment which in my opinion is already god enough. I have a vision, about Internet Explorer 8.1 ... those guys created an April fool that is everything but not a fool. Come on Microsoft, let others replace your old, problematic, slow, JScript engine, and let us developers be free to create Web Applications as we would like to do ... please give to Google whatever they need to make V8 IE integartion possible, and let us dream about a not that far possible Web future!
Sunday, April 19, 2009
Internet Explorer and its inefficient sort implementation
This is just a quick post about how much IE team cares about JavaScript performances ...
Guess how many times Internet Explorer compare results? 17583 times, against a.length - 1 in other browsers.
Nice stuff guys, I guess for big arrays a manual reimplementation could perform better, am I wrong?
// generate an array of 1000 elements
var a = new Array(1000).join(",.").split(","),
calls = 0;
// call sort method incrementing the conter
a.sort(function(a, b){
++calls;
// return zero, nothing should change
return 0;
});
// discover the monster
alert(calls);
Guess how many times Internet Explorer compare results? 17583 times, against a.length - 1 in other browsers.
Nice stuff guys, I guess for big arrays a manual reimplementation could perform better, am I wrong?
Sunday, March 15, 2009
Multiple Upload With Progress: Every Browser No Flash !!!
Update: released official version in Google Code, cross browser, and easy to use. blog enry
Ok guys, this is a quick and dirty entry in my blog. I need to write documentation, create the project in Google Code, explain better what I have done and how it works.
I do not want to give you the zip right now because I have to change name (silly me do not check before) and to do last tests ... but basically, what I have created this week end, is a graceful enhanced multiple file upload manager compatible with Chrome, FireFox, Internet Explorer (5.5 or greater), Opera, Safari.

The manager wrap an input type file and manages it allowing multiple files selection, where supported, or one after one insert with possibility to remove one or more file from the list.
Everything is absolutely customizable, since the wrapper is entirely in CSS, the library has a language namespace for errors or messages, and events are created by developers.
In those browsers were Ajax upload is not supported, the progress bar is simulated, but there is the feeling that something is happening.
In FireFox, where Ajax upload is supported, the progress is still simulated but at least the size, sent or total, is real.
Stay tuned for the official announcement, enjoy the demo in my website.
Quick thanks and credit to Silk Icon Set from famfamfam!
P.S. Yes, there is a file type filter as well, Flash like, and I have solved server side $_FILES problem with Safari 4 ... but please wait next blog entry!
Ok guys, this is a quick and dirty entry in my blog. I need to write documentation, create the project in Google Code, explain better what I have done and how it works.
I do not want to give you the zip right now because I have to change name (silly me do not check before) and to do last tests ... but basically, what I have created this week end, is a graceful enhanced multiple file upload manager compatible with Chrome, FireFox, Internet Explorer (5.5 or greater), Opera, Safari.
The manager wrap an input type file and manages it allowing multiple files selection, where supported, or one after one insert with possibility to remove one or more file from the list.
Everything is absolutely customizable, since the wrapper is entirely in CSS, the library has a language namespace for errors or messages, and events are created by developers.
In those browsers were Ajax upload is not supported, the progress bar is simulated, but there is the feeling that something is happening.
In FireFox, where Ajax upload is supported, the progress is still simulated but at least the size, sent or total, is real.
Stay tuned for the official announcement, enjoy the demo in my website.
Quick thanks and credit to Silk Icon Set from famfamfam!
P.S. Yes, there is a file type filter as well, Flash like, and I have solved server side $_FILES problem with Safari 4 ... but please wait next blog entry!
Wednesday, January 28, 2009
32 bytes, ehr ... 9, ehr ... 7!!! to know if your browser is IE
Update another clever trick from comments, which I will explain later:
it works, doesn't it?
The reason is simple, if we consider "\v" as a vertical space, browsers interpreter that check in this way:
where "not one" is always false, considering that 0 is always casted as false, and every other number is casted as true.
Internet Explorer will ignore the vertical space, trying to cast a "v" character into a number, thanks to the sign (plus or minus, it does not matter)
I read a lot of comments in both Ajaxian and other places ... well, guys, this is a trick as conditional comment is.
The day IE will interpret correctly the "\v" character, Opera or some other browser could implement conditional comments as well.
That's my simple point of view:
conditional comments could be stripped out from minifiers (not MyMin) and make code difficult do understand or maintain while this 7 bytes trick is portable, minifier/packer safe, and extremely easy to maintain (the day IE will be able to return a false, we'll have solved almost every cross browser problem thanks to JS2 but just in case, all we need to do, will be a simple replace with the isIE.Next trick)
Note this trick is library/hack proof. If you think that execScript check is enough, for example, consider this: top["execScript"]=null and/or libraries that implements execScript for other browsers.
if(!+"\v1") // true only in IEif("\v"=="v")// true only in IEtry{IE=window=!1}catch(e){IE=!0}
it works, doesn't it?
The reason is simple, if we consider "\v" as a vertical space, browsers interpreter that check in this way:
!(+
1
)
where "not one" is always false, considering that 0 is always casted as false, and every other number is casted as true.
Internet Explorer will ignore the vertical space, trying to cast a "v" character into a number, thanks to the sign (plus or minus, it does not matter)
// How IE interpreters the code
!(+"v")
// where
isNaN(+"v") === true
// and where NaN is implicitly casted as false
About conditional comments
I read a lot of comments in both Ajaxian and other places ... well, guys, this is a trick as conditional comment is.
The day IE will interpret correctly the "\v" character, Opera or some other browser could implement conditional comments as well.
That's my simple point of view:
conditional comments could be stripped out from minifiers (not MyMin) and make code difficult do understand or maintain while this 7 bytes trick is portable, minifier/packer safe, and extremely easy to maintain (the day IE will be able to return a false, we'll have solved almost every cross browser problem thanks to JS2 but just in case, all we need to do, will be a simple replace with the isIE.Next trick)
Note this trick is library/hack proof. If you think that execScript check is enough, for example, consider this: top["execScript"]=null and/or libraries that implements execScript for other browsers.
Saturday, January 10, 2009
Internet Explorer Object watch
Update
As Luke suggested, there is a method remove in the watcher that should solver leaks problem while the new version should be supported by most recent Opera, Safari, FireFox, and Internet Explorer.
Main updates:
----------------------------------------------
We all complain about IE and its non-standard attitude, this time I would like to introduce a non standard feature, as Object.prototype.watch is, for Internet Explorer.
The watch method allows validation, control, monitoring, over a generic object.
This means that we can control properties assignment with one, or more, callbacks.
I used a weird strategy to implement this feature in Internet Explorer and it is based on DOM and its IE feature called onpropertychange.
Accordingly, it was not possible to create an Object.prototype.watch, while it was simple to implement a createWatcher callback.
A first example, based on precedent one, is this one:
Another example is based on validation, or better, a one shot assignment over the watcher:
Cool?
The main one is that the for in loop will not work as expected over a watcher element because it is a DOM node and it will expose every property.
Another one could be about memory leaks and/or low execution, since there are a couple of things to do during assignment.
The good part is that the watcher and the watched will have the same property value, except for those attributes that we cannot modify in a DOM node (style, for example).
Last but not least, happy new year! :D
As Luke suggested, there is a method remove in the watcher that should solver leaks problem while the new version should be supported by most recent Opera, Safari, FireFox, and Internet Explorer.
Main updates:
- the watcher is always another object and not the original one
- to safely destroy the watcher use its destroy method and then delete it
----------------------------------------------
We all complain about IE and its non-standard attitude, this time I would like to introduce a non standard feature, as Object.prototype.watch is, for Internet Explorer.
What is watch and why we need it
The watch method allows validation, control, monitoring, over a generic object.
This means that we can control properties assignment with one, or more, callbacks.
var man = {};
man.watch("name", function(propertyName, oldValue, newValue){
// propertyName: name
// oldValue: undefined if it is the first time, the old one otherwise
// newValue: new assigned value
return "Mr " + newValue;
});
man.name = "Andrea";
alert(man.name); // Mr Andrea
watch for Internet Explorer, about my implementation
I used a weird strategy to implement this feature in Internet Explorer and it is based on DOM and its IE feature called onpropertychange.
Accordingly, it was not possible to create an Object.prototype.watch, while it was simple to implement a createWatcher callback.
(function(watch, unwatch){
createWatcher = watch && unwatch ?
// Andrea Giammarchi - Mit Style License
function(Object){
var handlers = [];
return {
destroy:function(){
handlers.forEach(function(prop){
unwatch.call(this, prop);
}, this);
delete handlers;
},
watch:function(prop, handler){
if(-1 === handlers.indexOf(prop))
handlers.push(prop);
watch.call(this, prop, function(prop, prevValue, newValue){
return Object[prop] = handler.call(Object, prop, prevValue, newValue);
});
},
unwatch:function(prop){
var i = handlers.indexOf(prop);
if(-1 !== i){
unwatch.call(this, prop);
handlers.splice(i, 1);
};
}
}
}:(Object.prototype.__defineSetter__?
function(Object){
var handlers = [];
return {
destroy:function(){
handlers.forEach(function(prop){
delete this[prop];
}, this);
delete handlers;
},
watch:function(prop, handler){
if(-1 === handlers.indexOf(prop))
handlers.push(prop);
if(!this.__lookupGetter__(prop))
this.__defineGetter__(prop, function(){return Object[prop]});
this.__defineSetter__(prop, function(newValue){
Object[prop] = handler.call(Object, prop, Object[prop], newValue);
});
},
unwatch:function(prop){
var i = handlers.indexOf(prop);
if(-1 !== i){
delete this[prop];
handlers.splice(i, 1);
};
}
};
}:
function(Object){
function onpropertychange(){
var prop = event.propertyName,
newValue = empty[prop]
prevValue = Object[prop],
handler = handlers[prop];
if(handler)
attachEvent(detachEvent()[prop] = Object[prop] = handler.call(Object, prop, prevValue, newValue));
};
function attachEvent(){empty.attachEvent("onpropertychange", onpropertychange)};
function detachEvent(){empty.detachEvent("onpropertychange", onpropertychange);return empty};
var empty = document.createElement("empty"), handlers = {};
empty.destroy = function(){
detachEvent();
empty.parentNode.removeChild(empty);
empty = handlers = null;
};
empty.watch = function(prop, handler){handlers[prop] = handler};
empty.unwatch = function(prop){delete handlers[prop]};
attachEvent();
return (document.getElementsByTagName("head")[0] || document.documentElement).appendChild(empty);
}
)
;
})(Object.prototype.watch, Object.prototype.unwatch);
A first example, based on precedent one, is this one:
var // original object
man = {},
// create its watcher
manWatcher = createWatcher(man);
manWatcher.watch("name", function(propertyName, oldValue, newValue){
return "Mr " + newValue;
});
// assign name property
manWatcher.name = "Andrea";
// retrieve original object property
alert(man.name); // Mr Andrea
Another example is based on validation, or better, a one shot assignment over the watcher:
var obj = {},
watcher = createWatcher(obj);
watcher.watch("test", function(prop, oldValue, newValue){
return oldValue === undefined ? newValue : oldValue;
});
watcher.test = "one assignment";
watcher.test = "never again";
alert(obj.test); // one assignment
Cool?
About limits
The main one is that the for in loop will not work as expected over a watcher element because it is a DOM node and it will expose every property.
Another one could be about memory leaks and/or low execution, since there are a couple of things to do during assignment.
The good part is that the watcher and the watched will have the same property value, except for those attributes that we cannot modify in a DOM node (style, for example).
Last but not least, happy new year! :D
Tuesday, September 09, 2008
Internet Explorer Security Hole - A Better Example
Again, about the security hole I talked about last posts, but this time with a really simple example.
More details in my old post I wrote last Saturday, the one that few people read carefully, understanding what was going on.
This is not a new bug, it exists, and I knew it, since 2004 or before, when banks did not use security checks, yet.
Kind Regards, and please choose another browser until Microsoft will not fix this problem for every IE.
How does the example work
- Open Internet Explorer, whatever version
- Go in this page
- Write a fake user name and a fake password, or a fake email address and a password
- Click Submit
What does the example do
- Emulates user actions via javascripts
- with some version of IE, it could be able to grab both fields values
- in any case, it demonstrates you that every site could steal your compiled fields in every other site, if the autocomplete option is not forced to be disabled
What could do a malicious, and hidden, code
- steal your data
- steal your email
- steal your credit card information (a really famous company, as example, suffers this problem, so somebody could steal credit cards details of million of people)
- steal your details
- steal your searches via common search engines
- etc, etc
More details in my old post I wrote last Saturday, the one that few people read carefully, understanding what was going on.
This is not a new bug, it exists, and I knew it, since 2004 or before, when banks did not use security checks, yet.
Kind Regards, and please choose another browser until Microsoft will not fix this problem for every IE.
Monday, September 08, 2008
Internet Explorer 6, 7, or 8 exposes users data via JavaScript
Ok, ok, I know these are Google Chrome dedicated days, but how can be possible that my last post did not receive attention at all?
Maybe with this title somebody will read more carefully what I wrote few days ago ... or maybe not, who knows? :?
Maybe with this title somebody will read more carefully what I wrote few days ago ... or maybe not, who knows? :?
Subscribe to:
Posts (Atom)