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

Monday, February 13, 2012

Web Workers - Current Status

A quick one about workers after few tests.

Mobile

Workers are apparently nowhere in Android devices stock browsers. The only one able to bring workers seems to be Chrome in ICS.
As alternative, both Opera Mobile and Firefox Beta work without many problems.
About iOS, version 4 does not support workers while version 5 does and quite well.

Desktop and Data URI

Workers are almost fine everywhere except IE9 ( surpriiiiiiiiiise ) but there is one thing not a single browser does except again Firefox and Opera, accepting "data:application/javascript;" with or without base64 encoded code.
On mobile side this is supported again by Opera Mobile and Firefox Beta without problems but on desktop, and not only ...
  1. Safari works only with external files while inline data uri are supported only via file protocol
  2. WebKit nightly does not support inline data uri even through File protocol
  3. Chrome does not support inline data uri neither via file protocol nor online
  4. Safari Mobile does not support inline data uri, at least online
  5. Chrome Mobile does not support them at all


Why Bother With Data URI

Quite simple, Workers are a mechanism to detach some logic from the main thread and execute it in the background. The possibility to create inline Workers means we could create a sort of Threads manager, delegating runtime ad-hoc functions to perform certain tasks handling all requests from and to the main page.

Workers Until Now Are Not Good

Not only the serialization and deserialization problem does not scale with large amount of data, probably the only reason you would think to use a worker for some job, but the DOM security exception thrown with data URI and for no reason on earth is yet another limit for this technique.
Current status, except for data URI, is that you may need webkitPostMessage rather than simply postMessage in order to at least optimize data transfer between global objects, but on the other hand, the dream we all have about "HTML5" keeps fading out every time I understand I need to prefix something, either if I use CSS3 or JavaScript (i.e. requestAnimationFrame).

Disappointed, nothing else to add.

Friday, December 30, 2011

Learning From 2011

It's time to summarize at least few mistakes or epic fails of the year, hoping the next one will try to follow a better direction.
I won't mention anything related to war, politic, Berlusconi, or fashion related stuff, other more prepared than me will do via pictures or posts, all I gonna talk about is the field I am concerned about: web and mobile web oriented technologies and facts.
The order is completely random, so grab a mug of coffee, take few minutes, and read 'till the end, forgetting for once tl;dr philosophy ;)

The Partially (Multi)? Touch Device Case

This has been the most annoying fact of the year: vendors going out with freaking powerful mobile devices with touch or multi touch capable screen/hardware not exposed through the browser and only available for native apps.
We are not talking about potentially "dangerous" technologies as WebGL could be, we are talking about the most basic thing able to break 140% the user experience.
If a user plays a native game or use a native map, as classic Map application could be, she will naturally use at least a finger, or more, to interact with the screen. Interaction does not mean scroll the page and nothing else, interaction means full control of what the user is doing with the screen.
As soon as the user surf the web, the browser pretends to know what the user would like to do on the screen without giving web developers any control over those actions.
The inconsistent behavior comes when the viewport meta tag is used to block, as example, the zooming in and out gesture because the whole layout has been developed for a static viewport that should not change.
In this case, only few vendors ( Apple ) or browsers ( Opera Mobile ) got it right, any other vendor with a WebKit based browser got it wrong. Here a few examples:

IE9 Mobile Epic Fail

IE9 is a great browser, compared with all other previous version, and it's freaking fast. This is true for both desktop and mobile phones but in latter case, IE9 is an epic fail when it comes to User Interaction.
There is no bloody way to intercept a user moving a finger on the screen, and standard W3C Touch Events are not supported.
You may think: oh well, I gonna use mouse events then ... and you are wrong, these are not fired until the user release her finger so ... forget about it, no "scroll" hacks will work as expected there ... also why on earth when everybody else is disabling JS actions during scrolling, IE9 Mobile fires it all the time?


Sad part is that Microsoft is investing a lot into HTML5, but if the most basic thing as Touch Events are, is not there, no reason to have the fastest mobile Canvas implementation because no game will be interactive, and no web app can be created as desired.
Hopefully IE10 will simply follow W3C exposing both Touch and TouchList in a meaningful way ... please don't screw this or few developers will even consider to write software for this browser, thanks.

webOS 2 Sad Fail

I have upgraded few minutes ago my Pre 2 to webOS 2.4.4 ... and I was expecting more from this update. My Palm Pre 2 exposes correctly multi touches through the system, but the web browser does not expose them and this is freaking annoying. Same IE9 behavior and at least at the end of 2011 I was expecting such simple browser update able to bring my Palm to the next level: User Interaction Through The Web ... FAIL.
The good old native Google Maps application for webOS 2.0.X is gone. This app was working like a charm and it was exposing multi touches through the multi touches capable screen ... now I have a slower and flicking version of Bing maps that is not even able to render pinch/spread without loosing the position on the screen since everything gets stuck truly easily.
Now, I have no idea why this happened and why somebody wasted time to do this ... it's just worse than before and the browser still does not expose multi touches ... come on guys, this phone did not deserve to die like this.

Ultra Powerful ... "broken" Androids

It does not matter if we have 16 cores in our expensive smart phone when developers life is made harder for no reason ... with most recent Android phones we could create any sort of web application but here again, no-f*cking-body exposes TouchList via browser except few tablets out there.
OK, still better than nothing, as it is for IE9 Mobile, FF Mobile ( I will come back later to this one ), or webOS browser, but how comes 3rd parties browsers such Opera Mobile are able to bring TouchList and expose multi touches through the multi touches capable screen and native browsers are all lacking of this basic feature?
You don't even want to know how we managed to bring multiple touches in android devices, all you need to know is that is basically a hack and it requires a native application wrapper and this is, in my opinion, ridiculous!
Nowadays, all users with a friend that uses an iPhone, will consider the multi touch web app broken in its android: come on, I use two fingers in other things why I cannot do the same in this web site/application?

FireFox Mobile Fail

I don't know where to start with this browser ... I mean, guys, this is not Desktop, this is a touch screen. If you decide that the user cannot even scroll a paragraph horizontally because your freaking cool settings or bookmark view has to show up instead, you should create your own device and make the phone 3 times larger: 1/3 for the actual screen, 2/3 for your things nobody expect to appear during navigation.
About touches, at least most recent version implements touch events but performances are still too bad compared with native browsers or Opera Mobile, and the fact settings or bookmarks show up when we touch close to the edge of the screen, plus the fact AFAIK there is no way to avoid this, make this browser not suitable for full screen web games/apps based on canvas: slow and unusable ... please fix/drop this!

UpdateIt must be said that latest FF mobile brings better canvas performances and apparently it exposes a not so fast WebGL. I dd not know this the moment I wrote this post so FF Mobile is definitively already going to the right direction.

iOS Gesture Events VS Others

These are not standard and nobody should care. The moment we can rely in TouchList and multi touches exposes through this interface, the problem is solved 'cause we can implement by our self any gesture we want.
No need to wait 'till on spread/pinch are implemted and documented, just please give us TouchList and take your time after to do things properly. TouchList has been already defined ... that's all we need so far, thanks!

The Curious Case of Opera Mobile

Opera did weird things this year ... it switched from partial ES3 support to full ES 5.1 support ... what the hell guys, congratulations! Still there is no way to understand numbers of this browser (again: Opera Mobile, NOT Mini) .
Today, I can say Opera Mobile is one of the fastest and most capable browsers I have been dealing with but the lack of many CSS3 features have been the arrow in the knee together with the fact Opera could have been the Phone Gap Like software of the year while they focused on ... I guess something else.
Don't give up guys, Opera Mobile is amazing and people may chose to download it as soon as most common HTML5/CSS3 things are working as expected and also you may expose freaking cool stuff without necessarily follow W3C, giving web developers the possibility to distribute applications directly through your browser as native wrapper ( and fallback to Webkit for iOS ) .
Opera has always been pioneer, and it's time to be pioneer on mobile too because on desktop I am afraid to tell you it's hard to compete. Firefox, Chrome, and Webkit Nightly, are really advanced and I believe bigger teams, what we are missing is a not so fragmented browser that works as expected in as many devices as possible because what I have seen with all webkit versions I have worked with this year was painful, hard, inconsistent, and WTF development oriented.
Last, but not least, If there is not SQL Database, don't put a native useless Database function on the global scope or shims are screwed and if you don't expose SQL Database, at least expose Indexed DB or shims are screwed.

Android Whatever

While many developers think that Android is an Operating System, I am every day more convinced that Android is a Super Kernel that has almost nothing to do with the Operating System itself.
There are too many damn versions of Android, and even same major versions do not guarantee anything.
Every device must be tested a part because every device, with every vendor specific gotcha, software, or extra cool stuff, may behave differently. Funny enough, while I was thinking this is true for the webkit based browser only, there are many exceptions device specific that do not work as expected even natively ... oh, come on, don't call it OS!
If we think about Windows, almost every piece of hardware is supported. Then we have the classic crapware every single vendor puts by default in its own distributed piece of hardware ... fair enough, at least most basic things gonna work as expected in all of them ... right?
With Android, the most basic free version has almost nothing. Cyanogenmod is the basic example, once you install it, you gonna scream for apps you expect to be there and it comes up you need the specific Gapp package ( Google Applications ).
Same thing with Kindle Fire, based on the very basic version of Android so common apps available for other tablets may not work or may not be there.
This means we can trust only a truly basic set of functionalities that are hopefully working in all distributions out there but you know, this is IT, expectations are rarely matching reality.
The performances tuning per each device is another problem, as problematic are performances of the same app through the browser compared with those through the native layer.
If you wrap your single touch full page canvas game into phone Gap, as example, you will realize how freaking fast it is compared with the same exact code through the browser ... why that? Security layer is off plus bound stuff is limited compared with the whole browser application ... fair enough? No it's not. The moment I realize it is possible to force HW accelerated rendering via native wrapper but it's not possible to do the same via browser I start screaming ... let us develop through the web or stop telling us you support standards because if these are limited intentionally then those not supported are developers themselves.

Mobile Web Apps Too Limited

I really hope I won't need to write a similar post at the end of 2012 but I am not sure there will be many progresses here ...
W3C is slow, plus it may waste their/our time. Web SQL Database is an example, something I loved screwed by dependencies free purist.
I have talked about Web SQL many times and right now I don't care about this specific topic, all I care is about moving forward.
Time to agree and promote such interface to drop it after 2 years is not the way to go.
Time to replace such interface with another one limited, slower, and not widely adopted as IndexedDB is, still not the way to go.
We need a database, please put it there one ASAP and drop 50Mb per domain/tab limit.
No fools guys, if the logic behind the Web is that user must explicitly agree give the user full control.
If a web application requires more than 50Mb give the user the possibility to increase the database.
All native apps do not care about how much space is used, these simply informs the user through system settings how much stored data there is. Google Earth, as example, even maps, these are heavy memory applications that do not ask every 5 megabytes if more space can be allowed ... this was another epic fail.
Once the user accepts the fact this web application would like to use the storage, create a way to simplify the task able to verify how much data is being stored and stop asking!
From UX perspective is like accepting an explicit file upload/manipulation and while the file is being loaded into ram asking every 200Kb if the user would like to increase the memory allocation for that file ...


What If Every Web Page Asks For Space

Nothing, same is for "what if every native app takes 4 gigs of space" ... either space is available or it's not possible ... is that easy ... but again, with an easy to access indicator and a limit that goes far beyond 50Mb the problem should not exist. User can clean the cache, or enable more space but it must be easy, as easy should be for web apps developers to understand the available space because if the device is full already, the 50 Mb limits is pointless in any case plus there are ways to trigger memory consumption behind the scene and fill up gigs of disk space/SSD ... once again, this ask on demand every time is an epic fail, imho.
FYI, the behavior I am talking about is in iOS, where Android asks only once if the disk access is allowed, then it silently fails after we reach the 50Mb limit.

Native VS Web App

Every browser is based on a native web view or similar concept, which means every browser could expose anything. I would like to be able to record user voice via web, to decode it via audio tag, to create real time video chat, to replace all native applications and to forget Android, iOS, webOS, blackberry, Symbian, MeeGo, Windows, whatever SDK ... I want to leave the SDK power to much more complicated things and I would like to be able to do most basic things via browser, all those things that the user could do with native apps, performances a part.
The gap between native and web app should be performances and nothing else indeed ... right now is: all possible nasty access to everything on native side, things that few users are rarely aware of, and almost no access to any functionality through the browser.
No idea if Chrome OS solved this but if it did, I am pretty sure it did with in-house solution, same Windows 8 will do, and this is annoying at least until a jDevice library will come out able to make all these private API consistent across all platforms ... as summary, why Mobile Web App development has to be so hard is a complete mystery to me: is it about your own markets? Fine, then stop selling us your browser is promoting Standard Mobile Web development because this sounds, so far, like a big lie.

Patent Oriented Development

When I heard that Apple patented a slide to unlock the screen I did not feel like "they are so advanced" ... I rather felt like "is anyone trying to patent my finger" ?
I move horizontally my thumb since ever and nowadays I know there is a patent for that and this is bad.
A natural movement should never be patented ... the graphic used to guide the movement could eventually be a patent but the way I do things not.
I don't want a patent to hold a fork, I don't want a patent for the position I use to sleep in a mattress, whatever weird sofa, or a chair, I don't want to do unnatural movements to unlock a touch screen.
What the hell is going on here ... if I use my nose to unlock my old android device I don't have to pay the patent indirectly, right?
Is this what is patent about? Yes, it is.
Patents are about intellectual property of whatever but the problem is that patents are expensive, are not necessarily predictable, and all these patents are doing is to block future development on top of it, unless is not the same company.
Patents are a sort of creativity barrier because if a company invents a generic something, nobody will even try to improve that invention due basic patent behind the original.
Example, I use my right hand to hold the phone and when I am talking with someone I put my right thumb on the right side of the phone.
If there is a button there, it's annoying, while if I have to swipe from left to right ... well, it's still annoying.
Will I ever implement a swiping gesture from right to left to unlock the screen because usually the way I hold the phone is with my right finger on the right side and it's more convenient to me to swipe the other way round as it is convenient for all left hand users? Nope, I don't even want to remember that thing exist, I have to create something completely new being careful that what I am doing does not touch the other patent ... cool, uh?

Hardware Patents

Same concept could be applied for hardware ... was that thing perfect? Yes, I pay the patent. Was that thing not perfect? No, I have to create something new ... even if based on laser(disc), the reason we all waited so much for new standards after the CD.
This happened with Compact Discs, and it brought us DVD first and Blu Ray after. In the meanwhile, another standard better than CDs but a bit less capable than Blu Ray died ... fair enough, we have new hardware for all these technologies but how comes in the hardware field the patent problem is not so strong as it is for the Software one?
3D TV, all vendors are making one, as well as CD players, DVD players, and Blu Ray players ... nobody cares about patents here, at least not the way we all do when it comes to Software.
I don't have any answer for this but I believe patents should be re-evaluated in their meaning because in the fastest field ever, as technology/software is, something that last for 10 years is too much and price to pay is too much as well as too much is the time between the patent pending and the patent applied status.

ES6 Focus

I have talked about this as well ... it's about what's truly needed today, at least in the Mobile Web Development, and the JavaScript.Next focus, often completely abstract over not-so-needed topics as syntax sugar and boring classes.
iOS5 brought massive performances boost to all Apple devices but even having the fastest and complete browser out there, Safari Mobile cannot do miracles when it comes to performances.
The side effect of not having performances oriented techniques in JavaScript and DOM world is that average web developers are not able to create cool stuff without draining the battery or being slightly fast only with most recent mobile devices.
The need for performances in this Mobile era should be priority number one for W3C and a possible ES 5.2 milestone, after that take even 5 years to improve syntax with all sugar you want, if necessary, at least we can push Mobile Web Development to its limit in the meanwhile while many new proposals won't bring anything interesting, as far as I can read, performances speaking.
We can deal with the fact protected and private variables are absent or different in JS, what we cannot deal with anymore is that a proper and fast 3D API is not available, that Parallels are not available, that WebWorkers are useless when it comes to move data back and forward, that postMessage requires a window.open which require a click which is too slow but cannot be faked ontouchend or window.open won't work anymore because not explicit ... that IndexedDB does not provide native way to join data and speed up queries, that DOM manipulation is slow, that we don't control repaints and/or reflows, that binary Arrays are still slow, that Structs like classes/objects are missing, that CSS3 is bringing logic in the view with lack of control ... etc etc ...
I don't care if Proxy are in the browser, if these are 2X slower than good old JS on mobile, you know what I mean? We need more performances now and more APIs finalized to have access to hardware layers only SDK can expose without granting any better usage than an experienced web developer.

WebGL Partial Fail

First of all this is not yet a standard, regardless the effort of the kronos group, which means browsers like Internet Explorer will never adopt this ... fair enough if we can shim through Silverlight but here comes the second point: WebGL, as well as Silverlight, are not available for mobile.
Apple exposed it for Adds only, where adds are most likely those responsible for bad Web performances, generally speaking, due massive usage of Flash or arguable usage of automations to bring canvas Adds able to slow down all netbooks and tables out there .... congratulations, I'll never get this choices ... WebGL not for developers but for designers of adds only ... can I say brilliant?
Too few mobile devices are exposing WebGL if not none of them while basically every mobile device has a GPU compatible with Open GL 2.0 ES
Still experimental, true, and already available mainly for Chrome browser where Webkit, as well as Firefox, could do the same or truly similar. The direction WebGL is taking is not good at all and I can't wait to see cool demonstrations able to run with all WebGL capable browsers ... so far, not many of them ... and this is bad.
Sony enabled WebGL in its latest version of Android, still about fragmentation, so I am expecting at least every other vendor to bring WebGL in our current devices already capable ... it was a massive fail to drop it for the whole 2011, cool things may have been experimented already on devices plus typed Arrays could have been used more even for non WebGL related tasks.

CSS3 Partial Fail

As mentioned before, CSS3 are becoming the most messed part of the whole Web stack, mobile and/or desktop. Examples with counters to change dynamically text via :after selector ... is it just me? I mean ... dafuq is that?
Internet Explorer dropped the most misunderstood proprietary feature as expression was and webkit is introducing any sort of unmanageable logic inside CSS3? ... counters? webkitTransitionEnd withou webkitTransitionStart? No way to trigger properly transitions if not without asynchronous rendering? Lots of hacks to make them work cross platform with control through JS for something written in CSS?
CSS3 is bringing MVC in Web world without the C and if we would like to create robust behaviors/interactions/applications that make sense, programming speaking, we should forget the case where the user has no JavaScript because CSS3 is becoming indirectly strongly dependent on JavaScript for many reasons ... why not bring standard DOM method to control states via JS, rather than control partially what is supposed to happen via CSS3 only? I don't get it, I have seen cool stuff, but I have not seen cool stuff adopted cross browser and I am not seeing cool stuff easy to handle via JS and/or vice-versa.
CSS3 needs notification into the JS world or we gonna have Photoshop like power without tools to control what we are doing.

As Summary

I have more things to say, and more I forgot but I thought a rant on 2011 was needed at least to check, in one year, what happened, what improved, and what did not change at all.
I hope all people that are doing hard work on daily basis to promote a better web won't take anything I wrote personal and will simply consider the point of view of somebody that works with all these things on daily basis so ... it's my personal feedback, on what I think should change ASAP and specially for mobile web development.

Happy New Year Everybody

Monday, September 26, 2011

About Me At JSConf EU

I know I am not in the list of speakers page yet, but I am actually in the official schedule already.

It's about jsconf.eu and my talk on Sunday morning at 10:45 entitled ...

Buzz It For Real !

... the tortuous road to Mobile HTML5 Apps

For the very first time in my life I will not represent just myself during a conference. This time I will talk about few ideas, problems, and solutions, we have faced during the "still in beta" development of our Mobile HTML5 Applications.

I will talk about some problem completely ignored by majority of HTML5 developers providing concrete real-world examples, and solutions, over tested code.

I know Sunday comes after the first conference party and I hope you, as well as me, won't be too drunk to follow my talk :D

Of course a SpeakerRate page was a must have so see you there and enjoy the conference!

Thursday, August 18, 2011

HTML5: How To Create Downloads On The Fly

this is a quick one I have implemented already in fuckn.es in the create angry memory button logic ...

The New Download Attribute

Hopefully soon, most updated browser will implement the download attribute in hypertext links (aka: <a> tag)
The quick summary is this one:
The download attribute, if present, indicates that the author intends the hyperlink to be used for downloading a resource. The attribute may have a value; the value, if any, specifies the default filename that the author recommends for use in labeling the resource in a local file system.

And this is a basic example:
 click here to <a href="resource234.txt" download="license.txt" > download the license </a> 


What Is Download For

Well, I am pretty sure you have read at least once in your life this kind of extra info beside a link:
right click to download the content and "Save As ..."
Moreover, I am pretty sure you have created at least once in your server a page able to force a generic file download.
All these instructions and server side headers/files may disappear thanks to this new attribute, also because there's no such thing as "right button" on touch screens, neither in some newer device pointer.
If the file is meant to be download, it will ... cool?

Create Downloads On The Fly Via JavaScript

When I have read about it, I have instantly realized the potentials of this attribute combined with inline data uri scheme.

Only HTML5 ?

Nope! Please note that many browsers let us already practice this technique. Some may open the file in a new blank page while some other may download directly the file as is for Chrome and the CSV example.
As graceful degradation, the "right click" procedure will still do the trick.

Downlaod Canvas As Image Example

First example is a classic one: how to save a canvas snapshot as image via "click".
 // basic example function createDownloadLink(canvas, name) { var a = document.createElement("a"); a.download = name; a.title = "download snapshot"; a.href = canvas.toDataURL(); return a; } // some paragraph in the page document.querySelector( "p.snapshot" ).appendChild(createDownloadLink( document.querySelector("#game"), "snapshot" + (-new Date) + ".png" )); 

When the user will tap/click on the link, the browser will simply start the download. No server side involved at all!

Save A Page As PDF

Thanks to this technique we may use same trick to produce a PDF file out of whatever web page.
 // basic example function createPDFLink(fileName) { var doc = new pdf(); // whatever content you want to download var a = document.createElement("a"); a.download = fileName; a.title = "download as PDF"; a.href = doc.output('datauri',{"fileName":name}); return a; } // some paragraph in the page document.querySelector( "p.saveaspdf" ).appendChild(createPDFLink( "document-" + document.title + ".pdf" )); 

Of course if the page content changes we can replace the old link with a freshly new created one.

Save Table As CSV

Well, another classic here, the csv format out of a table. This is a basic but working example ;)
 <script> // really basic example function tableToCSV(table) { for (var header = table.querySelectorAll("tr th"), rows = table.querySelectorAll("tr td"), hlength = header.length, length = hlength + rows.length, result = Array(hlength), i = hlength, j; i < length; ++i ) { j = i % hlength; j || result.push("\n"); result.push(rows[j].innerHTML); ++j % hlength && result.push(","); } i = 0; while (i < hlength) { result[i] = header[i].innerHTML + ( ++i < hlength ? "," : "" ); } return result.join(""); } this.onload = function () { var a = document.body.appendChild( document.createElement("a") ); a.download = "table.csv"; a.href = "data:text/csv;base64," + btoa( tableToCSV(document.querySelector("table")) ); a.innerHTML = "download csv"; }; </script> <table> <tr> <th>name</th> <th>age</th> </tr> <tr> <td>Dan</td> <td>33</td> </tr> <tr> <td>John</td> <td>32</td> </tr> </table> 

Most likely we can test already above example even if the name won't probably be the chosen one.
For safe base64 encode, compatible with UTF-8 pages, have a look at this script ( base64.encode() and base64.decode() ).


Different developers asked already about compatibility.
As I have said before, we need to differentiate between "download" attribute compatibility AND inline data uri link compatibility.
In the first case I don't know browsers that will force the download with the specified name yet, but I'll update this section as soon as I know someone.
In the latter case, IE9, Chrome, Firefox, Safari, Webkit based, and Opera seem to be already compatible.
The main problem/limit I have spotted in fuckn.es is the size of the data uri, in certain cases we may need a decent/fast machine otherwise we may end up killing RAM and CPU performances.
IE8 is compatible as well except IE8 has limited data uri for CSS images, as example, and I expect same limit for this technique.
Bear in mind when all browsers will be compatible, we will still have data stream limit problem, or better, really big files has to be parsed on the fly in one shot, no "download progress" possibility.


As Summary

... now you know ... ;)

Thursday, July 28, 2011

because shit happens

When you spend half week of holidays recovering because of a dislocated shoulder, when you come back and spend 1 month recovering after a shoulder surgery, or for any other smaller or bigger shitty situation life could offer us, there is now a customisable way to express our anger: fuckn.es !



100% Embedded HTML5 Application

One project that always fascinated me is py2exe, an utility able to convert whole python applications into a single executable file.
This concept is similar in OS X Applications, where everything is transparently contained in a single file.
I have tried to reproduce a similar concept with this stand alone web page application where the manifest is hilariously the only external dependency, totally superfluous but necessary for mobile devices.
In any case, fuckn.es is a portable, "copy and paste source ready to go", cross platform tiny app, where rather than #! /bin/sh at first line, the user should simply double click it and run within a (modern) browser.
All images, sounds, and obviously CSS, HTML, and JavaScript are included. This surely avoid advantage of self updated web apps but nobody could stop me to implement a simple JSONP call to the website to compare versions:

// current version
var current = "0.0.1";

// update notification example
JSONP("http://fuckn.es/?v=" + current + "&fn", function(latest) {
if (latest != current) {
if (confirm(
"New version " + latest + " available.\nWant to update?"
)) {
location.herf = "http://fuckn.es";
}
}
});


Mobile Oriented Navigation

While the app works in both Desktop and Mobile browsers, latter are surely more friendly with the implemented navigation / interaction.
The whole app can be managed with touches and gestures:
  • touch the body to see the anger in action (one up to three seconds)

  • tap one of the top buttons to access internal sections

  • swipe sections to change them or tap other sections for faster tab scrolling

  • scroll sections if these do not fit on the device screen

  • interact with fields by selecting them, no need to explicitly apply changes

  • tap again the current opened section to close it and eventually see changes applied
All of this is surely experimental but it was fun to create such mobile friendly interface that is usable through mouse and trackpad as well .... you know, specially on Mac we are getting used to act via gestures and I am pretty sure this website won't be the first one that interact more like an iPad app on bigger screens.

Current and future HTML5 capabilities

fuckn.es tiny app is based on many HTML5 concepts such File API, Audio, more related to the audio element, CSS3, and soon coming Web Storage to make changes persistent. I did not bother myself to make a fully cross browser app since one of these days all major browsers should support these features, including the input with capture microphone, right now usable to customise the audio providing a valid source.

JSONP Based Setup

The whole logic is based in a single fucknes function call, passing an object such:

fucknes({
color: "#F00",
background: "#333",
text: "OMG",
audio: [
"base64encodedSource1",
"base64encodedSource2",
"base64encodedSourceN"
],
image: {
"00": "base64encodedImage00",
"10": "base64encodedImage10",
"11": "base64encodedImage11",
"30": "base64encodedImage30",
"31": "base64encodedImage31",
"60": "base64encodedImage60",
"61": "base64encodedImage61"
}
});
The same concept is used to restore a previous or custom state file via record section and soon I will put an extra input able to JSONP online a custom configuration. Of course this app makes sense if people will start customise and distribute angers all over the net :)

Inline Download

As soon as W3C committed the link download property I have thought: how cool is that, I can create a base64 version of a text or whatever it is and set the filename into the download property ... and this is what I have done. There are no browsers yet compatible with the download property so right now if we create a snapshot of the current configuration we need to "right click" and save as, the result will be a text/plain file directly decoded for us by our browser.
This is the first time I see such technique to avoid big post or redirect to the server in order to download something for the client and as solution it seems pretty damn cool, isn't it?

No Server Code Involved At All

The last cool part is that the whole app can be used within the html file itself, there is no need of the server side and once these apps will be able to run in a trusted mode, same as native apps do, through the FileReader API, the Web SQL Storage or similar, and all next generation JS features, we can truly, and eventually, think of creating native like applications using exactly what we know already: no 3rd parts frameworks or application involved ( phonegap, Qt, appcelerator, etc )

As Summary

This little website has been one of the most stupid and futuristic personal projects I have ever made. It was simply fun from the beginning till the end, the silly represent your anger idea and the everything in one place with no server needed implementation.
It took a little while during my spare time and even this post has been prepared in different moments but eventually I have been able to activate my german PayPal account and the host finally worked as expected after DNS changes ( my fault here, I did it wrong ).
I hope you can at least appreciate the idea and why, have a little laugh or contribute with some customisation.
What's next? It could be face recognition to put anger through our camera snapshots or who knows what else ... stay tuned, and have fun ;)

Monday, July 11, 2011

Random Rant On CSS3 Transitions

Update
Thanks to @gregersrygg for his link and hints, this is a hackish way to solve the problem apparently cross browser and trustable ... still a hack!

// this save one char, how cool is that!
!function(document){

// (C) WebReflection (As It Is) - Mit Style

// we all love function declarations
function redraw() {

// clientHeight returns 0 if not present in the DOM
// e.g. document.removeChild(document.documentElement);
// also some crazy guy may swap runtime the whole HTML element
// this is why the documentElement should be always discovered
// and if present, it should be a node of the document
// In all these cases the returned value is true
// otherwise what is there cannot really be considered as painted

return !!(document.documentElement || 0).clientHeight;
}

// ideally an Object.defineProperty
// unfortunately some engine will complain
// if used against DOM objects
document.redraw = redraw;

}(document);
// tested with Opera, Firefox, Chrome, WebKit

... at the end of the day, nothing changed about this post because the summary is still that we do not have an official/standard way to do things properly and we need to use hacks to simplify our daily tasks.



so here the summary: there is no fucking way to use CSS3 transitions properly!

The Problem

We put everything on the DOM and we let nodes come in and out all the time or we are screwed!
CSS3 transitions are freaking cool and freaking painful at the same time.
The classic scenario is to pollute the whole DOM once or many times with our random appended/inserted HTMLElements.
The goal is to keep the DOM as clean as possible still being able to let things land on the DOM in our desired way.

setImmediate bullshit

Rather than improve the single setTimeout(callback, 0) classic case, the classic hack that supposes to make things work as expected and at the same time the classic timeout rarely stored as integer to clearTimeout later does not scale.
This is the reason vendors/HTML5 people/whoever decided to add another unshimmable function: setImmediate, which supposes to be used the same way "setTimeout with zero delay" is commonly used.
If vendors screw a bit up the same way FireFox did, where somebody pushed in some release a requestAnimationFrame without thinking about the counterpart clearRequestAnimationFrame, setImmediate becomes useless as well as setTimeout 0 is if nobody takes care of clearTimeout or clearImmediate function.

The Problem, Once Again

We appendChild a node with margin-left: -100px, a transition property equal to margin, and we add the className that supposes to put the margin-left: 0.
To solve this we need to appendChild the node then abstractly wait for the browser to paint and after, eventually, set the new class.

var div = document.body.appendChild(
document.createElement("div")
);
div.style.marginLeft = "-1000px";
// now we want the transition to marginLeft = 0 ... HOW?????

If by CSS3 above div has transition margin monitored, the only way to trigger the transition is to set a random timeout expecting that the browser renders in the meanwhile ... caus if it does not happen, we won't simply see it.

Why It Is So Hard

Unfortunately is most likely Web Developers fault, in the meaning that browsers are doing everything possible to optimize callbacks.
What we think is synchronous is just a matter of asynchronous, impossible to control, redraw actions behind the scene, where of course if we change 3 times classes to the same node browsers just consider last status and that's what they draw.

The Missing API

The more we have illusion of powerful features the more we screw up our architectures and layouts .... there's not much to do here except a bloody synchronous document.redraw() method, something that supposes to tell the engine: hey, I wanna you to consider the current layout so that after I can change it and you can consider these changes.

Will it be too hard for the CPU/GPU? Who cares, I mean, with all uncontrolled and theoretically optimized redraws/repaint operations we have every N milliseconds, how can a developer choice hurt so much?

mozAfterPaint

About Events, the cool part is that we can create them on JavaScript side and dispatch them whenever we want. Now, this paragraph notification is something we cannot fire in a meaningful way but it supposes to tell us ... exactly what? No idea, because the problem is that I do not want to control the status of the DOM via unpredictable setTimeout behavior, I wanna be able to tell the browser that status is OK now, would be so kind to draw the whole fucking thing for me, please?

As Summary

I hate lack of power under the HTML5 is for developers flag, I see setImmediate as a joke that I will be forced to use at some point for who knows which reason, but I still miss the possibility to properly control all these CSS3 transitions power via JavaScript, and once again, messing up between the view, and the controller.

Told'ya it was a rant!

Tuesday, July 05, 2011

Online Base 64 Converter

Update apparently I am more than late since datauri.com does similar stuff ... oh well, better two options than nothing, right? Thanks @mathias for the update.


Right, you may think this is the most useless thing ever but actually embedded content is freaking cool and this is the reason I have created a truly simple page in 3site.eu/base64.

What The Hack Is That

Nothing truly special, you choose a file, you get its representation in base64 compatible with inline data url.

Best Available Option

... is converting data accordingly with your browser: who better than a browser can know how to understand inline data? Chrome or any other HTML5 Enabled Browser should work offline without problems, but if you are masochist and stubborn, it may fallback into server side encoding. Latter case may be dropped as soon as my cheap space in my cheap website will suffer too many requests so ... did I say already use a decent browser?
And that's all folks :)

Monday, April 18, 2011

Native HTML5, the new IE6, and bla bla bla ...

I don't know about you guys, but I am kinda bored by all these news and tweets against Microsoft ... don't get me wrong please, you may have realized over these years I have rarely been that nice with M$ products, but there is time to complain, and time time to move forward and appreciate, at least, what we have now compared with what it was 10 years ago.

IE6 is Death, Long Life to IE6

Back in time, IE6 was the kick ass browser every web developer was dreaming about:
  • tons of security issues to hack in order to have access to any sort of private data (btw ... it's still like that ...)
  • hybrid JScript/VBScript engines with different privileges for each language and none of them based concretely over a standard
  • the predecessor of what we call today Ajax
  • hybrid box model able to understand the worst markup we can possibly imagine so ... wannabe developer friendly (I'll be back to this point later)
... and so on ... with all its glory ...

Why NO future IE will be the next IE6

Now, over last 10 years many things happened:
  • Firebird changed its name: Long life to Firefox
  • Webkit made its path down to any sort of device
  • Chrome became the must have browser
  • Opera reached version 11.50-beta-HW-accelerated-maybe
  • we are not alone anymore ... !
We are not living anymore in that era where WEB was letting us think about spiderman, internet was working only inside intranets, and no competitors were showing off yet.
We live in a different segment of the browsers timeline, a space where web surfers are more concious, less passive, and specially less ignorant ... we live in a time-frame where internet is almost everywhere and it's even portable in our pockets ... is IE there? We never cared about it, and this is the future!

Feel Free To Choose!

The Antitrust somehow forced Windows OS to let the user chose one out of 3 browsers ... I mean, more than this I wonder what do we expect ...
I have never seen such technique in any other Operating System ... but we still complain whatever IE will block people forever ...
Moreover, even if there is no choice, nobody in my family is using Internet Explorer, unless it's at work and hopefully to use work related services, not to go on Facebook or the HTML5 version of Youtube ... you know what I mean ...

Legacy Support: The Beginning Of The End

The most common excuse we can ear from a Company about the usage of IE6 is this notorious "legacy code" buzz word. For all those non techy people out there, when you ear this word this is the translation: "We don't have money to update our slow and deprecated infrastructure and we don't have enough competent people able to migrate data and business logic into something better that could bring only more value to our infrastructure and our daily basis work. Since as I have said at the beginning we don't have money, we cannot temporarily hire external Companies that would be able to do that as well ... uh, I forgot to mention we are simply out of the market 'cause we are stuck in year 2000 or earlier and new technologies ... which new technologies?".
Moreover, if we want to be reached with our online services by these companies and their employees, it is not just about the browser!
All PCs in these companies are most likely relict unable to perform any good with latest "special FXs" we all would like to put in our web ( transitions, shadows, WebGL, etc ... )

In an Ideal Web World

This is how the web development would have been in the ideal world every developer is dreaming about:
  • write once run everywhere exists
  • jQuery would have never been created
  • hobbyist and wannabe web developers, the specie more than ever growing these days mainly thanks to precedent point, would be the only web developer category so ... engineers, go and get a real job!
  • browsers won't have a name since they all act the same and there is no difference except some performances number
I am kinda joking but let's face reality. "Web For Everybody" does not mean that all browsers will be the same, it means that we must be good enough to be able to bring the web in as many browsers as possible ... this is our job, and if everything would be the same, our job would be the most boring ever ... isn't it?
The reason me and many other thousands like me are challenged on daily basis are indeed limits we keep facing in different environments.
These limits may be extremely hard to solve, cross platform speaking, but thanks to latest technologies, thanks to latest browsers, and thanks to our hard work, we can already bring what we really want in every platform: this is our job!

IE9, IE10, and the Native HTML5

I honestly do not mind about marketing words, neither users mind that much. They eventually update their browsers and if no happy, they change it again: easy.
What I do mind is that IE9 supports for HTML5 is good enough to bring fresh new content and design in every house.
What we can show today in this browser and others is unbelievable if we think we had to deal with bloody PNG alpha channel and IE6 for ages!
Why do we complain that much then?
I do believe the only day we should really complain is the day we have used all possible techniques, fallbacks, and alchemies we could imagine to shrink 100% of IE9 potentials, the same we have done over these years with IE6 ... isn't it?

Premature Complaining VS Research

The main reason people adopted libraries such jQuery is the ability to bring "unthinkable" features even in older browsers. Hacks for rounded corners, DOMContentLoaded, canvas shims, Flash fallbacks, Sockets, PNG32 support, and many others have been all over the place in latest years ... and what do we do now?
Rather than appreciate the fact we don't need them anymore and focus on what we really need next we would like to cuddle ourself behind the excuse "as usual, IE lacks behind".
Now, honestly, ask yourself how many times you have been dealing with WebSockets, Database API, WebWorkers, WebGL, and all newest technologies we may already complain about without having a clue what the hell are these useful for ... and without considering that we will always have a way to fallback.

Is WebGL missing? Not Really, Not Now

Is not that since the browser has it, everybody can use it ... is much more. WebGL opens doors to the GPU and I bet +80% of web developers out there have zero knowledge about OpenGL ES 2.0 potentials and GLES shaders language.
Apple clearly confirmed they have no intention to put WebGL support in their devices, and the reason is kinda logic: it is easy to put the GPU in an infinite loop and drain the battery or make the device unstable.
Microsoft had different reasons to do not invest much into WebGL: DirectX
Chromium invested time to create Angle which aim is to convert OpenGL ES 2.0 calls into DirectX and make WebGL possible in Windows OS as well.

Different Fallbacks

If we really care about WebGL, if we really need to put such heavy content in our web pages or our advertisements ( shaders + textures + runtime parse/translate/compile ) we can always fallback into shims through Silverlight or Flash Player, as soon as it will implement Adobe effort to bring hardware accelerated 3D content within.

Wasn't Flash Death? ... NO!

... and thanks gosh will hopefully never die! Flash has been our best friend for all those missing features now partially re-implemented in HTML5 and Flash has been always one step forward.
All those shims about storages, databases, files uploads, canvas, sockets and all the magic behind some library scene ... flash is not good but it's not that evil as well.

So, What's Next?

If it's about IE9 limits, we can simply wait that day we have discovered all possible ways to do what we need to do while if it's about WebGL we need some kick ass 3D developer with excellent knowledge of these 3D APIs: Silverlight and Molehill, aka Flash Player Incubator.
With these kind of developers out there we could have possible shims for WebGL or, even better, a jQuery3D library able to make WebGL development easier and, hopefully, without GPU loops and memory exhaustive problems.
Finally, what I really would like to see out there, is less "oh my god we are stuck forever again" and more "hey, I have spot this limit, let's figure out how to break it".

My 2 cents and happy holidays everybody, I'll be back in few days.

Saturday, April 02, 2011

See You There HTML5

My uncle Paolo opened an Italian Restaurant in London, New Barnet, and I have been there few weeks ago to visit him and bring him my congratulations.
While this is absolutely not technical, the story I would like to tell you is ...



The Real Beauty Of The Web

HTML5 is probably the most overrated buzz word since the Web started existing, most likely even more misunderstood than Ajax therm itself.
Microsoft promoted his latest IE9 (and please use it if you like IE) behind the sentence Beauty Of The Web ... well, accordingly with Microsoft the web has always been beauty since Chrome, WebKit, Opera, and Firefox became real competitors ... but this is another story.
What many did not get about this HTML5, is that it's born backward compatible, which means that as document declaration it can be used right now and there is nothing to wait for...
The real value of HTML5 is the ability to bring newer techniques where available, still being compatible in W3C therms with all those old browsers that never followed strictly Web standards.
This is beautiful, not because I have been able to create the latest "kick ass website with fantastic special effects", simply because following few steps and remembering few rules, the landing page I have created for Paolo should work in almost every damn browser with relevant market share presence.

See You There ... For Sure!

we'll know the mobile web is "ready" when links to the desktop version are understood to be unnecessary
This sentence from @grigs perfectly summarize my idea of a landing page.
While I was trying to take some inspiration, in this case checking other restaurant websites, I have realized that most of them where:
  1. absolutely unusable from mobile devices and/or tablets
  2. extremely heavy to download
  3. entirely based on Flash Player
  4. massive portals ... I mean ... seriously, it's a restaurant, not a social network!


Compromised Usability: Less Customers!

I have been living in London for a couple of years and I think I know something about the classic Londoner life style. First of all for a London citizen is quite common to have an unlimited bandwidth contract for a smart phone and about 20 pounds per month, smart phone included. Secondly, London has quite frenetic life-style and the "show me what I am looking for: NOW!" moment is specially frequent during lunch breaks and surely a nice to have in all other cases.
If we land in a page that takes ages to be downloaded and does not give us instantly info we are looking for, in a restaurant case I guess a "where and what", we have to search again. Moreover, if the page uses all cool libraries and frameworks that have never been developed for mobile and all links and sections works only through these magic libraries, the user may be totally unable to access what he is loooking for: a place to eat!

Size Matters: The Annoyed Potential Customer

Many devices show on top how much data has been downloaded so far. If we see a progress bar that takes ages to be filled and a page that is empty for more than 5 seconds after the round-trip is completed, we start thinking the page is too heavy, the device is slow or, even worst, "FFS I am paying this bandwidth!".
It's true, the web could be scary for all those people that have a pay per surf contract and if these people are scared to surf the net it's only our fault. Moreover, if the page takes too long to be visualized we go back and we re-fine the search or we click the next result in the list, isn't it?

Flash Player and the Skip Intro Anti Business

The (in)famous player we all know, the one that still shows videos on Youtube, has been wrongly used since the beginning when it comes to Web content. The classic skip intro for a 500Kb of bullshit nobody is interested about is the biggest epic fail of the history of web. Put a link in the main page that points to the intro? That would have been too much user friendly so ... naaaaaaaa!
Even worst, many devices do not support the Flash Player since only lately this has become suitable for mobile devices without draining the little battery.
If your business entry point cannot be reach by all possible customers, you paid the "skip intro" to ruin the potential of your business since all Apple products, as example, won't be able to reach your business.

The Restaurant Community Epic Fail

When I have seen that Paolo created a facebook group, the first thought has been: well done uncle, keep it updated!.
When Paolo asked why the site I was planning to create could not have the community section, this is what I have answered:
  • it's a restaurant, not a social network
  • nobody comes back to a restaurant website. Once they reach the place, they'll come back to the restaurant, if happy, or they won't
  • if anybody is interested in your group, there is a link that points to this group ... and since facebook is the only place they will go back for sure, on-line speaking, let them chose to join the group and be notified via their home screen wall
Paolo understood my points, I still do not get why on earth a restaurant should create a community online with events notification, the registration form etc etc ... seriously, let social networks do this job and don't waste your time/money for this stuff ( KISS and YAGNI )

As Summary

I made this page as simple "best luck, uncle Paolo" present and over a week end and I hope you will like it. It is simple, it follows my favourite principles, and it's not pretentious as many other restaurant websites I have seen out there.
Why did I post about it? To make a bit of advertisement for my uncle delicious food from Tuscany, and to tell the story about how the web is still too much stereotyped and rarely ad-hoc from real business value perspective.
Keep it simple, and try to obtain the most important goal first: everything else could be added later, and only if you need it!

Sunday, December 26, 2010

100% Client Side Image Resizing

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

The FileReader Interface

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

The Canvas Trick

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

The Demo Page

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

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

// (C) WebReflection Mit Style License

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

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

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

}

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

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

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


The resample.js File



var Resample = (function (canvas) {

// (C) WebReflection Mit Style License

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

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

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

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

return Resample;

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


The Resample Demo In Action

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

Sunday, October 17, 2010

Pre Authorization Meta Tag Proposal

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

The Problem

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

Solutions

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


Proposal

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

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

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

navigator.hasGranted("GeoLocation")

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

Alternative

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

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

A usage example could be something like:

// script loaded after a while ...

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


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

What do you think?

Monday, January 04, 2010

Flash Satay Revisited

The most famous and W3 friendly technique to serve an SWF has been described in this excellent A List Apart Article ages ago. Unfortunately there are few problems with that technique, and being Flash Player still widely adopted, plus nobody has created yet a HTML5 friendly Satay method, here I am with this proposal/suggestion.

Satay Problems

There are at least a couple of problems with the good old Satay method:

  1. double SWF request, performed by almost every browser

  2. SWF impossible to cache, due necessary queryString for each different SWF so that classic c.swf will be required for each call



Object Tag Behavior

The Satay method is based over the assumption that an object tag, with a forced type, will help the browser to recognize the SWF.
At the same time, if Flash Player is not present or it has been disabled, Satay trick allows us to provide an alternative content inside the Object itself.
What we should be aware is that Internet Explorer won't execute any script tag inside the object.
At the same time, Internet Explorer and for some reason Opera as well, is the only one able to recognize and correctly execute the SWF without effort at all.
This is why my proposal relies into JavaScript, excluding Opera from the list of browser that should replace the object tag with the embed one.

Removed Data Property

The reason Satay loads two times the SWF, even if this is executed only once, is the data property. Once it is interpreted, Firefox and every other will understand the object itself and the classic "param name movie" will be re-evaluated. On the other hand, if there is a "param name movie" this is the one used by Internet Explorer to understand which movie should be loaded and interpreted via Flash Player plug-in.
Being this node available for every other browser as well, we can use its value to understand the movie replacing the whole object with an embed that will have the same src.

Alternative Content

If the Flash Player is not present/enabled the script won't perform anything except remove itself from the DOM since once executed, it does not need to do anything else. This means that the browser will simply show the alternative content being unable to understand what kind of object has been encountered, so we still have the nice layout fallback.

WebReflection Solution: HTML5 Layout Example


<!DOCTYPE html>
<html>
<head>
<script>
// generic function to initialize the SWF
function ASReady(msg) {
// IE + Others way to access the SWF exposed properties
(window["my-swf"] || document["my-swf"]).hello(msg);
};
</script>
</head>
<body>
<!--// regular object as if it is for IE/Opera only //-->
<object id="my-swf" type="application/x-shockwave-flash" width="43" height="72">
<param name="movie" value="alert.swf" />
<param name="FlashVars" value="msg=<?php echo rand(0, 100000); ?>" />
<!--// optional stuff to show if Flash Player is disabled //-->
<img src="alert.png" width="43" height="72" alt="" />
<!--// the tricky script, interpreted by every browser but IE //-->
<script src="satay2.min.js"></script>
</object>
</body>
</html>

Above layout passed without problems the W3 validator.
Please note that I am not using the classic query string to understand which file should be eventually loaded but a better FlashVars dedicated param node.
In this way the generic c.swf file can be reused without problems even via absolute url inclusion and finally cached directly via browser.

WebReflection Solution: satay2.js


(function (window) {
// (C) WebReflection - Mit Style License

// let's try to be future proof ...
"use strict";
for (var
// just ashortcut
type = "application/x-shockwave-flash",
// plugins property or ...
plugins = navigator.plugins,
// mimeTypes one
mimeTypes = navigator.mimeTypes,
// this operation should be performed only if it's not opera
enabledPlugin = !window.opera &&
// if plugins exists and "Shockwave Flash" is a valid property
(plugins && plugins["Shockwave Flash"]) ||
// or if mimeTypes plus $type exists and enabledPlugin is true
(mimeTypes && mimeTypes[type] && mimeTypes[type].enabledPlugin),
// grab the current script
script = document.getElementsByTagName("script"),
// set the current script as the last one (normal flow)
// find the parentNode (NOTE: quirks only)
object = (script = script[script.length - 1]).parentNode,
// create the element if necessary
embed = enabledPlugin && document.createElement("embed"),
// find out each param node, if necessary
param = enabledPlugin && object.getElementsByTagName("param"),
// set loop range
i = 0, length = enabledPlugin ? param.length : 0;
i < length; ++i
) {
// for each param, set relative embed tag property
embed.setAttribute(param[i].name === "movie" ? "src" : param[i].name, param[i].value);
};
// only if Flash player is present and enabled ...
if (enabledPlugin) {
// for each object attribute, set it into the embed node (id included, if any)
for (var attributes = object.attributes, i = 0, length = attributes.length; i < length; ++i) {
embed.setAttribute(attributes[i].name, attributes[i].value);
};
// replace the object with the embed node
object.parentNode.replaceChild(embed, object);
} else {
// remove this script, nothing to do
script.parentNode.removeChild(script);
};
})(this);

Via few checks and a couple of loops, above script, about 350 bytes minified and gzipped, will replace the object with the only element able to serve SWFs with browsers such: Firefox, Chrome, Safari, and few others.

WebReflection Solution: AS 2.0 Example

Just for this demo I have created an SWF which aim is to tell us if everything is working properly.

// dependencies
import flash.external.ExternalInterface;

// expose a hello callback to JavaScript.
// this callback accepts a string and it will perform a JavaScript alert
// with the text "Hello! " plus the received string.
ExternalInterface.addCallback("hello", this, function (msg:String):Void {
ExternalInterface.call("alert", "Hello! " + msg);
});

// initialize this SWF calling global JavaScript ASReady function.
// this.msg will be the variable set via FlashVars param
// for this demo, simply a random number generated via PHP
ExternalInterface.call("ASReady", this.msg);

// good old stop(); to avoid loops over the current frame
stop();

You can find a live demo in this page monitoring, or not, network traffic to discover that finally the SWF is requested only once rather than twice.
This should even speed up the execution thanks to non blocking embed.src nature and the missed, useless, second request to the server (a 304 that is still an extra pointless request).

As Summary

If we would like to make markup as clear as possible respecting validation and using all we can use to speed up layout execution, the only MUST for this method is a proper non quirk layout.
In any case, this was the purpose of Satay method as well so, if we liked that one, I am sure we can appreciate mine proposal.

Saturday, August 22, 2009

sessionStorage cross domain

This is just a quick post about my last HTML5 sessionStorage implementation for "every" browser and this is the summary:

  • Linear Storage Protocol finally consistent as a stand alone general purpose storage (string, file, request)

  • RC4 Stream Cipher key generation without breaking characters (\x00 not in the random range)

  • Cross Domain Support, if both site a.com and site b.com support my implementation, they will not delete or modify each other domain information

  • optimized boot strap for frames and iframes, the storage parsing and reassignment is performed once and not every time which means zero delay when an iframe is injected or more frames uses the same implementation


Finally, few bug fixes and this version is both W3C Draft compatible and cross browser.

Known Supported Browsers



  • Chrome 1 and 2, version 3 or 4 should have native support for Web Storage

  • Internet Explorer 5, 6, and 7, 8 has native support for Web Storage

  • Opera 7, 8, 9, and 10 beta, hopefully 10 final will have native support

  • Safari 3, version 4 has native support for Web Storage

  • Firefox whatever version, since it supports Web Storage since version 1.5

  • Google Android and iPhone, but latest WebKit releases should support Web Storage


This is a mixed list of almost all A-Grade browsers but about Android and iPhone, the total amount of available RAM could be 2 Mb.
It is not suggested to store in any case massive amount of information but so far I have putted every kind of library avoiding server requests for each tab session and without problems.
The sessionStorage aim is, in any case, to remember an arbitrary amount of data for each session and for each tab, surpassing cookies limits without number of keys or amount of data limits.

This project will be part of vice-versa library in order to make vice-versa the cross browser "lingua franca" W3 framework able to bring standards where these are not present yet.

1.4 Special Guests


I would like to say a big thanks to Jonathan Cook (J5 in WebReflection comments) for his suggestions, patience, and ideas exchange ;)

Sunday, August 16, 2009

W3 HTML5 Storage - What Works, What Does Not

My last sessionStorage is basically ready to implement storage events but apparently I cannot implement them right now. Why not? Doing some test I just discovered a lot of inconsistency for each browser which supports Web Storage in core, so here I am with a little report and some suggestion.

The Correct Way To Set or Get Items


Every single example I've read so far about Web Storage is not respecting standards defined by the official draft, even if related browsers respect the official API.

// bad sessionStorage usage example
if(sessionStorage.myKey !== null){
// not implementable with old browsers
// it could inherit from a modified Storage prototype
// it could be a false positive with native API
} else {
sessionStorage.myKey = "myValue";
// requires getter/setter, improbable with other browsers
// it could overwrite native properties or methods
// sessionStorage.key = "value"; will *break* the object
};

// W3 standard suggested Storage usage
if(sessionStorage.getItem("myKey") !== null){
// implementable with my standard solution
// it *should* *not* interfere with prototypes
// it *should* never be a false positive
} else {
sessionStorage.setItem("myKey", "myValue");
// it does not require get/set alchemy in other browsers
// it *should* *never* create conflicts with native methods
// or properties
};

The problem here is that if we follow W3 we are "safe enough" while if we use the quirks way to access or set properties, we will never know how the browser will react. An error because we tried to overwrite a native property or method? A silent operation that will break the object? A silent operation that will not break anything but that will make the logic inconsistent?

Which Browser Does Not Break Itself


Apparently, the only browser that implements internally a private dictionary, rather then set or get values from the sessionStorage instance itself, is Firefox. Both Internet Explorer 8 and Safari are able to make a sessionStorage, or a localStorage, useless. My implementation? It does not break the object, Firefox behavior!

// IE8 and Safari break theirself

sessionStorage.key; // native method
sessionStorage.key = "value";
// sessionStorage.key is broken, privileged property
// key with value "value" instead

sessionStorage.setItem("setItem", "break it!");
sessionStorage.setItem;
// the string "break it" rather than the API method
// setItem is not usable anymore in the whole page

As we know that we should never extend Object.prototype, how come every browser and every related example here suggests bad practices and/or allows us to easily break these objects?
Via official W3 API and bug fixes, we would like to be absolutely sure that setItem will never break the object itself and that getItem will always be the native API method.

Empty Key Support


OK, this is not a massive issue cause an empty string as key is something too silly to use.
On the other hand, since a Web Storage should support any kind of key as is for a generic object, where object[""] = 123 is normally saved, I wonder why Firefox browser does not save anything and it does not fire any kind of error as well.

// how to perform a ghost operation in Firefox ...
sessionStorage.setItem("", "empty string");
sessionStorage.getItem("") === null; // true !

I would like to have a unified behavior here as well ... don't you agree?

Storage Events - Nobody Compliant


This is the most interesting part of my analysis about Web Storage implementations, nothing is working as expected.
Firefox and Safari do not fire events at all, or at least I have not been able to do it.
Storage Events should be fired in the document, for gosh knows which reason (I rather prefer listeners in storages or directly in the top context, since everything is about the top window context).
Apparently storage events are two: onstorage, and onstoragecommit.
Both events are not described yet in the official draft so these are how Internet Explorer implemented them, and in an inefficient way.

// Internet Explorer is the only one
// able to fire storage events

document.onstorage = function(e){
alert(e); // undefined, global event instead
};

document.attachEvent("onstorage", function(e){
alert(e); // object Event ... hooorray? NO
e.key; // undefined
e.storageArea; // undefined
e.newValue; // undefined
e.oldValue; // undefined
e.target; // undefined
e.type; // storage, nice one
});

Funny enough, a web storage event in IE fires with clientX and clientY properties, extremely useful for a storage operation, isn't it? It does not matter, the problem is that there are no extra arguments and every expected property is not there.
At least, we have an event that fires in every storageSession present in the page, nested pages (i/frames) so it is usable as listener.
Accordingly, first usage of sessionStorage events will require developers skills to be implemented:

document.attachEvent("onstorage", (function(){

// this closure is necessary to
// create a memory variable
var modified = null;

// above variable is useful to manage
// events
return function(){

// unless we do not check each property
// in the storage, there is no way to understand
// what has been changed here

// we check if the sessionStorage is trying
// to tell us that something has been changed
// get("modified") will be null until it is set
// if we have more than a context (frames)
// we would like to perform the task just once
// this is why modified variable is used
if(modified !== sessionStorage.get("modified")){

// we can decide which action we should perform here
// and we should prevent next event execution
switch(modified = sessionStorage.get("modified")){
case "change userName":
// do some query or something else
// with the userName
sessionStorage.get("userName"); /// etc etc ..
break;

case "otherAction":
// ...
}
}
};

// define something
sessionStorage.setItem("userName", "Andrea Giammarchi");
// nothing is performed in the event

// now we want to perform something
sessionStorage.setItem("action", "change userName");

})());


Above example is just simple and not perfect but it is a hint about curent event management at least in Internet Explorer.
As Douglas Crockford did when He discovered JSON, we could enrich our event notifier protocol using JSON rather than plain strings, it is up to us.

Should I Fix Other Browsers ?


At this point I could decide to fix Firefox and Safari plus add events in my implementation for every other browser.
The problem here is that standards are not definitive and IE is alread messing up these standards.
Being sessionStorage and localStorage completely different objects, a type property in the event with value "storage" does not help at all to understand which one out of two has been changed ... or maybe, since onstoragecommit has never been fired in my tests, this event will be associated exclusively to the localStorage only ... who knows!
If I implement this behavior I gonna slow down events assignment due to addEventListener or attachEvent wrappers.
The alternative is to call, if present, the onstorage event for each document part of the same session. Still, it should be in core and a fake event object could just cause more problems so I am kinda stuck with storage events but I am pretty much happy about the rest cause everything seems to work as expected.

As Summary


There is one thing I am concerned about: is this what HTML5 will mean for us? Do we need to test every single new interface to fix or change their behaviors? Isn't HTML5 purpose to make things more standard and less problematic?
As we can see there are already "gotchas" everywhere and for a single, simple, misinterpreted interface as Storage is.
Examples are different and confused, specially the Safari one uses both setItem, getItem, and direct properties access too.
Behaviors are not the same and there is something missing or different for each browser (I'll test Google Chrome ASAP as well).
Well, HTML5 is good, but we all should try to do not mess it up with quick but not-standard or problematic implementations.