My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.
Showing posts with label ie. Show all posts
Showing posts with label ie. Show all posts

Friday, December 28, 2012

A Cross Platform Inherit Function

This (apparently non working) gist gave me the hint. Stuff I've been dealing with for a while, finally used to bring an Object.create(firstArgOnly) cross platform/engine/client/server code that works. The name? inherit()

More Reliable Than Object.create()

The reason I didn't even try to polyfill the ES5 Object.create() method is quite easy: it is not possible to shim it in a cross platform way due second argument which requires descriptors features, highly improbable to simulate properly. Even if browsers support the create() method, inherit() guarantee that no second argument will ever be used so we are safe from inconsistencies within the function.

Forget hasOwnProperty !

Yeah, one of the coolest things about being able to inherit from null is the fact not even Object.prototype is inherited so we can create real empty objects without worrying about surrounding environment, 3rd parts obtrusive libraries, and the boring and slow obj.hasOwnProperty(key) check.
// some obtrusive code
Object.prototype.troll = function (up) {
  throw up;
};

// empty object in every browser/env
var dict = inherit(null);
dict.anyKey = anyValue;

// later on ...
for (var key in dict) {
  // only 'anyKey'
}
That's correct, objects that inherit from null are not affected by the Object.prototype ... really, we cannot even print them without defining a toString method!

Update: On IE DontEnum Bug

Unfortunately the fact IE does not enumerate toString and other native Object.prototype names is not solved here for the simple reason here we are not solving that problem, here we are solving inheritance. However,I think is a must know that even objects created via this function needs an extra loop or something like this:

Not Only Null

This function should just work with anything we might need to inherit and we can also inherit from inheriting objects without problems. Consider this an end of the year tiny present just to remind some basic concept about JS that is still valid: Objects inherit from Objects and that's pretty much it :) Enjoy and see you next year!

Tuesday, May 24, 2011

setTimeout and setInterval with extra arguments ... once again!

Funny discussion today on twitter about "why on Earth IE still does not support extra arguments with setTimeout and setInterval" ... oh, well ...

The execScript Behaviour

Somebody in IE team thinks that the rest of the world should avoid extra arguments because of a bloody edge case as the third argument in IE is:

// ... seriously ...
setTimeout("Msgbox('WTF')", 0, "VBScript");


What IE Users Could Do

Well, rather than create a closure every bloody time we would like to reuse a function with different arguments, something posible 10 years ago via ActionScript 1, every web developer (and not only) misses the opportunity to avoid closures using a de-facto standard for some unknown reason not part yet of ECMAScript specifications.
For those interested I will show an example later, right now let's think about a solution compatible with VBScript for those mental developers, as I have been, brave enough to still use this language for some purpose.

setTimeout(function () {
// a closure for *this* edge case only
// rather than all cases "trapped" because of this!
execScript("Msgbox('WTF')", "VBScript");
}, 0);


Exactly The Same Behaviour!

Yes, if we use a string for setTimeout or setInterval this will be executed on the global scope, regardless where we defined this timer.
Accordingly, the latter example via execScript does exactly the same, since execScript executes synchronously on the global scope, and once trapped behind a timer, nothing change, same result .... happy? No, you are not!

The Classic Closure

The most common situation where we have problems is when we have a portable function defined somewhere else and we would like to use this function passing certain arguments there.

// somewhere else in the scope
function doStuff(obj) {
obj.stuffDone = true;
}


// later in our super cool application
setTimeout(
// the infamous closure
function () {
doStuff(myObj);
},
1000
);

The worst case scenario is where we would like to define timers inside a loop and unfortunately this is a truly common pattern that causes me repeated WTF tilt in my mind:

for (var i = 0; i < 10; i++) {
setTimeout(
// the double infamous closure pattern
(function(obj){
// the infamous closure
return function () {
doStuff(obj);
};
}(collection[i])),
1000
);
}


Closures And Scope Lookup Costs

Every time we access an outer scope variables we do a lookup in the ... well, outer scope. Every time we create a closure we pass through a function expression activation plus we create a nested scope that has to perform a scope lookup to access the outer function/variable.
Whenever this description makes sense or not, here the test you can try with not so powerful devices or mobile phones and tablet.
In my Atom N270 netbook that test is quite explicit: 50% less performances for each nested closure and its inline invoke.

Speed UP!!!

I have already described this pattern but I keep seeing too few developers adopting it.

for (var
createdOnce = function (obj) {
return function () {
doStuff(obj);
};
},
i = 0; i < 10; i++
) {
setTimeout(createdOnce(collection[i]), 1000);
}

Above example creates 11 functions rather than 20, which means we allocate and garbage collect loop + 1 functions rather than loop * 2.

Speed UP MORE!!!

The best part is that every browser I have tested but IE supports one or more argument with both setTimeout and setInterval.

for (var i = 0; i < 10; i++) {
setTimeout(doStuff, 1000, collection[i]);
}

How many extra/redundant/superflous closures and inline invoke we have created? 0.

How Difficult It Is

.. not at all.
It's pretty straight forward and it costs nothing for IE considering that you never bothered with this problem and you reached this point rather than skip this whole post at the beginning ... well, thanks for your attention :D , and this is your solution:

setTimeout(function (one) {
// only if not supported ...
if (!one) {
var
slice = [].slice,
// trap original versions
Timeout = setTimeout,
Interval = setInterval,
// create a delegate
delegate = function (callback, $arguments) {
$arguments = slice.call($arguments, 2);
return function () {
callback.apply(null, $arguments);
};
}
;
// redefine original versions
setTimeout = function (callback, delay) {
return Timeout(delegate(callback, arguments), delay);
};
setInterval = function (callback, delay) {
return Interval(delegate(callback, arguments), delay);
};
}
}, 0, 1);


Not Obtrusive

If we use above script at the very beginning of our web page there are extremely rare chances that the next script won't be able to use already the fixed version of setInterval and setTimeout for IE only.
If another script includes the same logic nothing will be redefined for the simple reason that variable one will be there so no double reassignment will be performed.
In the very safe scenario, considering we are inside our bigger outer scope created for our library, we can define those references as internal:

(function(){
// the beginning of our lib
var
setTimeout = window.setTimeout,
setInterval = window.setInterval
;


// the runtime check showed before ..

// .. the rest of the lib

// the end of our lib
}());

We may eventually decide to use some "isIE" check via conditional comments on our pages, since the solution costs nothing once minified, and have a normalized de-facto, fast, easier, behavior for every other browser.
Here the inline synchronous re-assignment for latter case:

(function (slice, Timeout, Interval) {
function delegate(callback, $arguments) {
$arguments = slice.call($arguments, 2);
return function () {
callback.apply(null, $arguments);
};
}
setTimeout = function (callback, delay) {
return Timeout(delegate(callback, arguments), delay);
};
setInterval = function (callback, delay) {
return Interval(delegate(callback, arguments), delay);
};
}([].slice, setTimeout, setInterval));


Update ... and As Summary

Of course the lookup is much faster than function creation, and this is the dedicated test but this post is about the summary of lookup and the classic closure creation historically used only because of this IE inconsistency.
Less lookup plus less closures around are faster, and numbers are there ( meaningful with slower devices )

Tuesday, March 29, 2011

Rewind: getters & setters for all IE with cross browser VBClass!

spoiler: if once again everybody knew except me, you guys should do something to be better indexed in Google ... while if this is totally new and cool, well, you are welcome :)



Sometimes I am stubborn, so stubborn, that even if it was me writing this post, and this one after, I have never given up about IE < 9 getters and setters ... "there must be a way", I have thought during last days, and ... yes, eventually I have found the way!

Test Driven Developed Solution

I have decided the possible behaviour, I have implemented all use cases, and I have successfully validated them against all browsers I could came up, with the exception of a single test, the first one, which fails in those browsers unable to freeze an object ... well, these browsers are disappearing thanks to their suggested, or automatic, updates, so everything is fine.
Here the unit test that should cover 100% of the used JavaScript and/or the used VBScript where available (only IE < 9 so please don't freak out yet!)

The Horrendous VBScript for IE

This wannabe Web programming language has been there, and hated, for ages ... but actually, if we learn all its gotchas we may end up thinking it is not that bad!
The main problem is to learn this "whatever it is language" and trust me: you don't wanna do that in this HTML5 era ... do you ?!

Not Only Get & Let, There Is A "Set" As Well!

Where good old dojo experimental Observable stopped, I didn't.
I kept investigating what the hack was going on behind the scene, forcing my fabulous IE9 to digest such Jurassic web programming language as VBScript is.
What I have discovered yesterday evening, is that when we set a property to a VBScript "unknown" object the Let definition is invoked only with primitives, where primitives are all those JavaScript variables which typeof is not equal to "object", with the exception of null value, and "function".
Once discovered this, the door to a proper implementation able to behave the same in all browsers became easy, and this is why I have introduced a new Class definition, the VBClass

What The Hell Is VBClass

VBClass is a global function able to create global factories, and these are the rules for a VBClass definition object:

  1. the definition of a VBClass IS static, which means once we have defined the structure of our instances, we cannot add, delete, or change arbitrary the number of properties

  2. since VBScript does not accept properties that start with an underscore, the convention to define a property "protected" must be different, as example using the underscore at the end as Closure Library does for whatever reason

  3. if a definition property is a function, this will be considered an immutable method of each instance created via this factory

  4. if a definition property has a value, its reference can be changed at any time and with any kind of object, function included, but in latter case it will not be possible to attach method runtime, but it will surely be possible to invoke the function property via call or apply, specifying the current object



A Full Specs VBClass Example


VBClass("FullSpecs", {
constructor: {
value: function (arg) {
// calls the method
this.method(arg);
}
},
method: {
value: function (arg) {
// invokes the setter
this.getSet = arg;
}
},
getSet: {
get: function () {
// returns the "protected"
return this.getSet_;
},
set: function (value) {
// assign the "protected"
this.getSet_ = value;
}
},
getSet_: {
// default "protected" value
value: null
}
});

var
genericObject = {},
test = new FullSpecs(genericObject)
;

test.getSet === genericObject; // true!


Pros And Cons Of VBClass

These are a few of pros about the precedent described VBClass limits/behavior:

  1. we have to think more about what we really need in our class, forgetting the completely dynamic JavaScript behaviour

  2. we are forced to follow a better convention for what we would like to define "protected properties"

  3. we can trust our defined methods, and we have to stick with them. This is a good/common approach if we consider a constructor.prototype runtime change a bad practice

  4. properties are properties, so there is nothing ambiguous about what is a method and what is a property: only the method can be invoked directly through the instance/variable/object, everything else is a property and there is no magic context injection there, neither for set functions


However, there are few cons to consider about this technique: unified behaviour through hosted VBScript objects means slower performances!
This means that VBClass created classes cannot be used for everything and there must be a valid reason to choose them in favour of normal JavaScript functions and their prototype nature.
A good reason could be, as example, the creation of those public object that would like to implement the coolness of a robust, cross platform, getters and setters implementation ... but be careful! If these objects are created hundred times during our application life-cycle, the performance impact could be massive and specially for older IE browsers.
Fortunately, with mobile browsers, IE 6/7 for Windows Phone 7 a part that I have not tested yet, the ideal scenario should fallback into the Object.create implementation, the one used in the main file, the only one needed, hopefully, as soon as users will update their browsers.

How To Use VBClass

Grab the source code or the minified version from my Google Code VBClass Project. Once all VBClass files are in the same folder, you can simply include the VBClass.loader.js on the top of your page and the rest of the magic is done.

<script
type="text/javascript"
src="http://vbclass.googlecode.com/svn/trunk/min/VBClass.loader.js"
></script>

Please copy VBClass locally to avoid round-trip and obtain better performances (also the trunk version in Google Code is not gzipped).

Have fun with VBClass ;)

Wednesday, February 23, 2011

...btw, getters & setters for IE 6, 7, and 8 (almost!) : Object.createStatic

Update Yes, I did it: getters and setters for IE < 9 and other browsers


Update apparently Dojo framework explored this stuff before me



Re-Update: More limitations!!!


Apparently I have said "Hooray!" too early, @_bga told me that this way is compatible with primitives only since the moment we have a property with an object or a function, this will converted into string.
So: don't return objects or functions since these will not work as expected!
Well, still something tho ... I should probably change the title with a big "almost" ...



... pretty much, the "dream comes true" features that could open hundreds of doors for current Web development status is here, but before we can understand properly the example page, we surely need a bit of introduction about the topic ...

Getters/Setters For Everybody!

Getters and Setters are beautiful, powerful, and the ideal scenario for whatever developer behind any sort of API.
Getters and Setters work perfectly in all browsers but old IE, where the version is almost 8, due possibility to use Object.defineProperty at least with DOM prototypes and some hosted object, and it goes down to all versions we know: 7, 6, ... etc

How Does It Work

"Proxying" VBScript via JScript global execScript method, it is possible to create a VBScript Class that via factory pattern assigns a private JS object into VBScript instance, passing through a runtime create JavaScript function that will act as a factory to return the private scope object passed to create the relationship ...



IE Getters and Setters

I had the same expression when I have read something like this, but I have been too lazy to even think about a better solution.
I kinda regret I have abbandoned my VBScript experiments at some point but ... you know, I am mainly dealing with mobile browsers where IE, as exclamation, meaningful word, or acronym, is basically never mentioned.

Rewind, We've Got Getters and Setters in IE!!!

At least we have the possibility to create a static object, where "static" means that we cannot set runtime properties the way we use to with whatever JavaScript object.
In few words, and at least for me for the first time, we have to deal with properly defined Classes inside a prototypal inheritance based programming language, and one of the most highly dynamic I know.

Object.createStatic

I have tried hard to respect as much as possible new ES5 Object.defineProperties definition object, but it was not possible, for cross-browser consistencies problem, to preserve the first argument as te one that suppose to be extended via definition object, so here's the signature:

Object.defineStatic(
definitionObject:JSObject
):StaticObject;

And here the same example in JS code:

var Static = Object.createStatic({
// public
value: {
get: function () {
return this._value;
},
set: function (value) {
this._value = value;
}
},
// "protected"
_value: {
writable: true,
value: 123
}
});

// will invoke the setter
Static.value = 456;
alert(Static.value); // 456

// will throw an exception
// or it won't work
Static.whatever = "no way";


Not Suitable For Prototype

Unfortunately, if we want to preserve a cross browser behavior, we should consider that the "Static" object cannot be used as a prototype definition, due its "hosted" nature, which comes from a VBScript Class, and for this reason cannot be handled as every other object.

Suitable For ...

We can use this hack to create those kind of object that would like to be:

  • secure, it is really challenging, almost impossible in IE, to redefine a property that has been defined already via definition object

  • reasonable amount, being each Singleton creation truly expensive for the already slowest browser still on the market, aka IE < 9, we cannot benefit from this approach in order to create hundreds of instances during an application lifecycle

  • any sort of API, where the main entry point is always the same object, used mainly as a namespace, and the "magic" we would like to add could have "no limits"



As Summary

This stuff has been around for almost two years, and I am the first one that never thought about it too much, or never felt so much the need to have getters and setters in IE. Now, at least from what I knew so far, you can play with future oriented code, waiting for your worst enemy to simply die thanks to the market offer.
It's your call, I am just giving a hint ;)

Once again, the source code!

Tuesday, October 13, 2009

Internet Explorer Scope Resolution

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.

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!

Thursday, September 04, 2008

Security Basis, and an Internet Explorer data stealer

It has been about 4 years, or more, that I know about this problem, but for some reason I did not talk about it, scared by possible reactions.

In other words, I was waiting for some noise over the net, or some fix from Microsoft, but nothing is happening.

Actually, Microsoft is working hard on Internet Explorer 8, but the problem I am talking about, is still present ... so, I suppose it is time to tell you how dangerous this IE "feature" could be, and how dangerous could be to forget a little detail in a form, like the autocomplete attribute.

The magic autocomplete option


Every browser tries to make our net life as simple as possible, and when we start inserting data in an input field, it suggests us a couple of words or, if the name of that field is unique enough, directly the most probable word, name, or number, we are going to insert.
To perform this operation, we could start typing the name, or simply use the down arrow button to open the list of options, and choose, usually, the first one.

More magic than ever


In some old Internet Explorer versions, like the the 6th one, when we are filling out a login form, we simply need to insert the name, or email, and the password field will be magically populated.
This means that with 3 buttons, 2 down arrows, and 1 enter, we can perform a login.

Magic IE JavaScript


Internet Explorer allows JavaScript developers to fire events simulating user mode.
This means that if we have a focus on an input field, and we fire the keydown event, with down arrow code, the suggested list of options will magically appear.
At the same time, if we repeat the procedure, the first option is highlighted, and if we repeat the procedure again, the second option and so the third one, if any.
More beautiful, is that if we fire the event another time, this time using the enter code, the field will be populated.

How to steal information from the Internet Explorer users


Accordingly, if a malicious website is replicating a form, which user has filled out ones on a genuine website and a dedicated JavaScript starts automatically interacting with the replicated form, the Internet Explorer will silently expose user's information, previously used in "who knows" how many different websites.
A simple, well organized process could try different combinations N times, saving results in an object, or an array, and then sending that information via ajax or a basic get request to a server, allowing the malicious developer to save and reuse that information.

A real world example


To show you what I am talking about, I have created a simplified version of the described script.
Most important things to remember:

  • any displayed information, if any, will not be saved, but only displayed in an alert window, so with my example your data is still your one

  • only Internet Explorer, as far as I know, allows JS developers to create such malicious code to embed in a webpage (that's why I posted about FireFox crash, few days ago :))

  • apparently, IE8, and probably 7 too, do not let developers steal entire login information


To perform this test, you need to use Internet Explorer. If you have never used, or used it only to debug or develop some web applications, please try to login into your favourite web services, for example Gmail.
After that you can directly test my safe example page, and wait few seconds to know if my application was able to get your email account, or whatever else information.

Which websites expose user information?


I am sure this problem is not a secret for Microsoft IE Team, since in every login form, starting from hotmail, they force the atocomplete option to off.
Therefore, it is not possible to steal, for example, hotmail emails, but if you use the same address to login in to another website, which for some reason does not implement the autocomplete off option, it becomes obvious how thousands of spammers can obtain our email addresses in such an easy way.
Gmail login service (surprise!) does not implement the autocomplete off option, so if we use Internet Explorer to login into latter service, our Gmail account name could be easily exposed.
The worst case scenario ever, is represented by Credit Card Forms, where if nobody though about this "little security problem", our Account Name, Credit Card, Verification Code, and whatever else private information, could be grabbed by malicious websites, without us noticing it.
Of course, the expiration date is not that simple to retrieve, but what a powerful weapon this IE feature can be to enhance phishing?
Just try to imagine a page, with similar URL, that already contains all information, but misses only the expiration date, requiring user verification.

As Summary


Other browsers probably know about this problem, since nobody lets JavaScript interact with webpages in the real user mode.
The fix I can simply suggest, is to disable the autocomplete option in Internet Explorer or, even better, change the browser to be sure that if we are inputting our details on a website, that information will not be readable from any other website without our authorization.

Have a nice week end :P

Wednesday, March 12, 2008

Do You Like Browser Benchmarks? Here I am!

Hi guys,
today we will not talk about my last JavaScript ArrayObject creation :D

Today is the benchmark day, and in this case the test is as simple as explicative ... both Math object and scope are two things we use every day for whatever purpose in this baby Web 2.0 era!

Let me start directly with results (ORDER BY speed ASC):

Firefox 3.0b4
----------------------------------
regular avg time in ms: 9.98
scoped avg time in ms: 3.18
encapsulated avg time in ms: 12.98


Safari 3.0.4 (523.15)
----------------------------------
regular avg time in ms: 13.42
scoped avg time in ms: 6.42
encapsulated avg time in ms: 11.82


Opera 9.24
----------------------------------
regular avg time in ms: 13.82
scoped avg time in ms: 9.6
encapsulated avg time in ms: 17.64


Internet Explorer 8.0.6001.17184
----------------------------------
regular avg time in ms: 16.42
scoped avg time in ms: 6.82
encapsulated avg time in ms: 16.82


Firefox 2.0.0.12
----------------------------------
regular avg time in ms: 26.84
scoped avg time in ms: 42.06
encapsulated avg time in ms: 28.64


What kind of benchmark is it?

This is a double test that includes the usage of scoped shortcuts, and the usage of the object that you cannot absolutely get by without: the global Math one!

To understand better this kind of test, please look at these functions:

function regular(){
for(var i = 0, time = new Date; i < 10000; i++)
Math.round(i / Math.PI);
time = new Date - time;
return time;
};

function scoped(){
for(var round = Math.round, PI = Math.PI, i = 0, time = new Date; i < 10000; i++)
round(i / PI);
time = new Date - time;
return time;
};

function encapsulated(){
with(Math){
for(var i = 0, time = new Date; i < 10000; i++)
round(i / PI);
time = new Date - time;
};
return time;
};


The first one, is the most common in every day libraries / scripts, while the second one and the third one, are used by "a little bit more skilled" developers.

The second one, uses the same concept of my good old friend, the smallest FX library from 2006: bytefx

The scoped schortcut is absolutely the fastest way to use a global objet, constructor, whatever you want.

Just think about nested scopes, this amazing ECMAScript 3rd Edition more close to future than many other new program languages ... ( IMO, and sorry for exaggeration :lol: )

When you write the name of something in your scope, the engine looks obviously in the same scope, than in the external one, going on until the super global object, the window

This behavior is basically what should happen using the with statement as well ... but unfortunately, even if this is basically what's up, performances are clearly against the usage of absolutely comfortable with statement.

At the same time, there is one browser that you are probably using right now, that create a bit of confusion about everything I've just said right now: Firefox 2

With quite twice of time, using scoped shortcuts, this browser (the best I've ever used for years, and the one I'll use for other many years) reverse totally my conviction about how does scope work ... anyway, we are lucky because Mozilla staff is creating good stuff with Firefox 3 ... who cares about Firebird and other old versions? :D

Don't you really trust me and my results?
So do this bench by yourself :geek: