Wednesday, December 03, 2014

Toward New Adventures

TL;DR this is some sort of biography of mine which aim is to explain my decision to leave Twitter.

When in 2007 I moved to London without any concrete job offer it was after 6 months in Lugano, Switzerland, and 2 years of freelancing attempt made in Italy, a country at that time not really prepared for modern Web standards or the Mobile / IoT era.

The Great London

In those days when I was already writing and reading everything in Engligh (or some sort of) I could not speak a word of it and decided to do that kind of full immersion you have to do if you really want to learn a new language: avoid at all costs people that speak your language => avoid italians!!!
I was doing it well while I was paying by my own a full time English course, surviving in London as best as I could, considering how freaking expensive this city has always been!

Not only it has been a great new open minded experience, I've actually met best international mates at that time!
I've also passed my first job interview in a foreign language ... actually, my first technical job interview of all times since in Italy, back in those days, these were not common in this field and you could not find much if not being friend of a friend or relative to the random boss ... anyway ...

The career possibilities and the amount of overall opportunities this city offered to me those days were amazing, so amazing, that other companies from other European countries started contacting me; probably after seeing some result of my improved technical skills together with my improved foreign spoken language (still sort of).

In 2008 I was already dealing with the Mobile Web world and devices running something like Android 1.5 ... devices you cannot believe how ugly could be! Actually, let me disturb your mind with the following image representing my precious in those days:

you are welcome!

The Amazing Berlin

When the HR contacted me from Germany asking me to relocate to Berlin, in a city I've never seen before, for a language I've never ever learned properly even living there (almost everyone speaks English there, yay lazy me!), I haven't thought twice about the offered opportunity.

NOKIA has been indeed the biggest corporate I've worked for so far and its Berlin's offices a great place to work. I've been doing Maps and Mobile Web R&D for years there, ending up starting with other buddies the first large scale and Mobile Web performance oriented HTML5 Map application these days still known as here.com

That being said, when you're contacted from the number one portal of all social networks, and to live in a sunny and beautiful country as California is, it's hard to not try and see how it goes ... right ?

meanwhile ... in Dublin

I've been in Palo Alto for no longer than a weekend + a Monday and I should have realized going in the US ain't simple matter: almost every new recruited developer of the "rest of the world" have to be "parked" somewhere in the world until that day US opens door to H1-B visa applications, also with the possibility to not be accepted, having a blocked Passport at the US Embassy or similar stuff ... oh dear ... at least I've had the opportunity to spend 3 months in Dublin, which is a beautiful city in a crazy "wonderland like" country: Ireland!!! I've been traveling this country every weekend I could and there's not a single boring or not extraordinary place I remember ... just go there and visit it 'cause no words of mine could describe its beauty!

... passing through the Bay Area

As opposite to the never sleeping, rightly chilled and windy San Francisco, Menlo Park, where I've been working at Facebook Head Quarter, and Mountain View, where I've been living for few weeks, can be described as the most quiet places in one of the most welcoming climate I could experience so far. So quiet that if you like going out without having the paranoia to drive a car, you can shoot yourself on your toes just to have some extra fun ... no, really ... too damn quiet!!!

Incredible San Francisco

Once moved into SF in a lovely flat from year 1900 and at the starting of Haight & Ashbury, I started commuting to MP every day without problems since all evenings and weekends in the city were the best I could ask for!

During those days I was working together with the great team behind the Mobile Web oriented m. Facebook site. At the time I just joined the team for few weeks and things were exciting as hell but then something happened, something I wasn't expecting at all ... something that let me think a lot about why I was there and what I've been working on for years: Web standards and HTML5, in order to reach every person on the world, where every person means also all without a bloody expensive mobile device!

There have been honestly more to this single fact that made me change direction but let's say that knowing I would not have been stayed in the US for long time, I could choose between FB or a company strongly present on Web and its Mobile counterpart, which aim is to reach every person on the planet, and which Head Quarter was basically beside my door bell ... Ding Dong ... oh, Hi Mobile Web at Twitter !!!

what's cool about Mobile and IoT

First of all, you have to really forget all solutions developed last 20 years for Desktops: these don't work, are mostly superfluous since it's a relatively new start based on modern standards, and constrains are completely different.
Screen size, interaction, all possible quirks, premature APIs but way more reliable DOM, a small amount of RAM and slower possibly single core CPUs; if you've been developing for Desktop sites only you have basically no idea how different is the Mobile world, and if you think about Internet Of Things devices you are even further: every superfluous JSON.parse or generic object copy/clone for often redundant abstraction reasons *will* be a problem!!!

The TL;DR story behind mobile and IoT development is that it's challenging: you have to reduce operations and bytes at their possible minimum, also eventually resulting in blazing fast applications that will run smooth as hell on every cheap Desktop you can imagine so ... it's actually a win/win if you think about it!

There is also a lot of daily inevitable myth buster about most micro benchmarking people are so secure about, where "getters are slower than properties" arguments might cause a huge laugh since functions can be executed million times per second on crappy HardWare and, if everything else is badly architected, a getter is just the last problem you have for your business.
I remember me implementing a lazy runtime .super(argN) property resolver that never slowed down a thing and was relying on the arguments.callee.caller property to discover at runtime inheritance when necessary and as lazy utility ... no kidding, you've probably been worried or been told to avoid these things like poison, you don't know these have been used in production on the worst possible Mobile Hardware and without causing a glitch for years in one of the most visited existing sites!

Back to my story ...

US visa: a double face monster

While I'm very grateful for the incredible opportunity these US companies gave to me, I must say the visa situation in the United States is just ridiculous as fuck.
Not only after taking 6 months to collect all possible needed documentation in order to be approved for a H1-B, the green card process asked me even more documents, as if it was OK for me to be a tax payer without them being sure about who I was and what I was doing ( why asking again same shit otherwise ... ) but due these kind or improbable operations it took 2 years only to hear the message: "we can start with the Green Card process, it'll take probably a year and they might ask more documents" ... well, you know what US? Keep it for now, thanks!

If you work on Mobile Web, in a field that has seen its first immature light in 2005, and you are applying for a green Card as Mobile Web Expert, you must know that if you don't have a non existent in this world Mobile Web related degree, US offices will ask you to provide at least 8 years of experience on the field with old time companies original labelled papers, but with today dates and signatures ... as if nobody knows this is the fastest field on earth and companies I've been working for *ages ago* might not even exist anymore ... right?

Moreover, if it happens that you are married, your partner will have a lovely H4 visa which is the most ridiculous permit ever: your partner cannot do interviews, cannot work, cannot even do charity or put anything work related in the CV ... it can only eventually study and ... I guess cook and clean the house or make babies as I believe a H4 person is suppose to do ... I call it bullshit!

As summary, if you sum up the inability to provide concrete and real Mobile Web experience since 2005 and have to wait at least another year plus a partner once upon a time completely independent and with already two masters and 4 fluently spoken languages, so that going back to school wasn't exactly the most desired situation, and after dropping already a career in order to follow me, you realize that having the opportunity to go back in Europe and be free from all this would most likely come into your mind ...

Back in London!

Twitter have demonstrated once again to be awesome and to truly care, giving me the opportunity to join the amazing TweetDeck team in London that luckily was looking for a Web dev.
You know, they could have told me: "you know what? bye bye!" instead and I would have understood.
I must admit that after leaving Twitter, and after years of job offers from any company I could think of, I wasn't sure I would have gone anywhere else. Twitter is a great place to be and I've met great people in both San Francisco and London office. Tons of shit to learn, tons of challenges and a lot of freedom within the company where you can decide what to do and with who, in my case I've been lucky enough to even choose the place: London!

Toward New Adventures

These few months spent with a team able to create one of the coolest Desktop Web App I've ever dealt with has been surely memorable and also extremely intense. Going back from 6 years of Mobile to Desktop thought ... also brought me back to a place I've happily abandoned, but obviously not forgotten, years ago.
I can really work on Desktop web, I've even created polyfills for IE8 and IE9+ on DOM4 but unless it's for fun for some crazy new project, I am not sure I am capable of working on Desktop for long time so ...

I had to be honest to myself: the day I've realized I was working against my real interests, also putting less enthusiasm and effort than I'm used to, possibly affecting the team of excited and caring developers around me, I decided to be honest with the company that took care of me for the last two years and communicate it was time for me to go!

I will start fresh in 2015 by my own writing a book first, since few editors already asked me to for months now, and go on with Mobile and IoT development ( I am compiling natively on a Raspberry Pi my own JS oriented Operating System right now ... I mean, this is who I am, time for Web Desktop Apps is kinda gone for me but I love everything about Web and will support it anyway! )
Sometimes I guess one has to follow its instinct, and since this city has been my start point for 6 years of corporate related development, maybe it'll be a great start point for next 6 years of mobile revolution?

Put in this way, at least I'll have more time to blog about all crazy things I've been blogging these years :D

Thank you Twitter and thanks to all colleagues I've been hacking with last years!

Tuesday, October 14, 2014

Unusual tricks via Array .some()

A very good reason to use Array#some instead of forEach is that once a single truthy value is returned the loop simply stops.

This is not only more efficient, but also way more powerful than .indexOf(value) or eventually .contains(value) thanks to the callback that gives us the ability to perform any sort of synchronous check:
// entering in a chat room
if (chatRoomUsers.some(function admin(user, i) {
  return user.isAdmin;
})) {
  console.log('Watch out, this room is moderated!');
}
chatRoomUsers.push(you);
chatRoomUsers.forEach(
  room.sendEachMessage,
  you.name + ' entered the room'
);

/* example of room.sendEachMessage
Room.prototype.sendEachMessage = function (user) {
  user.sendMessage(this);
};
*/
The inevitable unfortunate caveat with .some(), compared to an .indexOf() approach, is that the returned value is either true or false, but when it is true we need eventually to loop that very same collection again in order to find the element we might want to keep in any sort of "should contain only one element per type" situation, as a list of users or products usually is.

1. A classic outer scope variable approach

The most obvious but tedious, boring, and quite error prone approach we could think about is the following:
// generic list of users
var lotteryUsers = [
  {ticket: 'Z1023', name: 'Z'},
  {ticket: 'AR1J5', name: 'F'},
  {ticket: 'F89DD', name: 'X'}
];

// the outer scope variable
var index;
if (lotteryUsers.some(function (user, i) {
  index = i;
  return user.ticket == this;
}, 'AR1J5')) {
  console.log(
    'Congratulation ' +
    lotteryUsers[index].name
  );
}
A simple way to avoid that reassignment each time could be doing it only on success.
lotteryUsers.some(function (user, i) {
  return user.ticket == this &&
         ~(index = i);
})
The ~ will simply ensure that the returned value will still be truthy, since any index, zero included, will be converted into its (i + 1) * -1 counter part so that 0 will be -1, a truthy value, 1 will be -2, still truthy ... and so on. We'll check later performance against always reassigning.
Another alternative could be used when functions are recycled instead of created each time.
if (lotteryUsers.some(lotteryWinner, ticket)) {
  console.log(
    'Congratulations ' +
     lotteryUsers[lotteryWinner.index].name
  );
}

// anywhere it is defined
function lotteryWinner(user, i) {
  return user.ticket == this &&
         ~(lotteryWinner.index = i);
}
In latter case the win over the outer scope variable and the tilde ~ trick works pretty well combined.

2. A common case based on RegExp

Since regular expressions update results in the global object each time, we can actually use this code to understand, as example, if a node program.js has been called with -j4 or --cpus=2 arguments, in order to limit the usage of the cluster module:
var numOfCPUs = process.argv.some(
  // the testing function, same RegExp each arg
  function(arg){return this.test(arg)},
  /(?:-j|--cpus=)(\d+)/
) ?
  // if it was true, we can use
  // the value contained in the $1 match
  parseInt(RegExp.$1, 10) :
  // otherwise we can require a module
  // and grab all the CPUs
  require('os').cpus().length
;

// in case we are in multi core env
if (1 < numOfCPUs) {
  var i = 0, cluster = require('cluster');
  if (cluster.isMaster) {
    // go multi core
    while(i++ < numOfCPUs) cluster.fork();
  }
}
Since the nature of the RegExp is this one since about ever, I wouldn't mind using a convenient and semantic approach recyclable per each different case:
// it would be untouched anyway ...
RegExp.test = function (v) { return this.test(v); };

// for any similar case 
var numOfCPUs = process.argv.some(
  // same function, different tests
  RegExp.test,      /(?:-j|--cpus=)(\d+)/
) ?
  parseInt(RegExp.$1, 10) :
  require('os').cpus().length
;

3. An index solution based on RegExp

We have reached the final trick of this post, the one that will combine the need to verify a generic value of an Array and store the index without bothering the outer scope or the function itself, suitable then with inline functions too.
if (lotteryUsers.some(function (user, i) {
  return user.ticket == this &&
         /\d+/.test(i); // <== see this ?
}, 'AR1J5')) {
  console.log(
    'Congratulation ' +
    // this is how you grab it ;-)
    lotteryUsers[RegExp['$&']].name
  );
}
Not only the regular expression inside the some(cb) loop will be created only if a check will be truthy, but we don't need to create outer scope variables or reachable callbacks since RegExp at the end will instantly give us that result.

Caveat

This works only if absolutely nothing else creates or use regular expressions between some() and the moment you address the result so ... do not ever call something else before you have retrieved the expected object, others pieces of code might be based on the same trick.
// GOOD
var value = arr.some(check) ? arr[RegExp['$&']] : null;

// BAD
if (arr.some(check)) {
  update(somethingElse);
  controller.emit('found', arr[RegExp['$&']]);
}

Performance

In order to have as many random cases as possible, I've added a test in jsperf.com which aim is to try all these approaches and see which one wins.
I think that's very irrelevant this time, since all approaches are mostly equivalent, but at least we have some little proof whatever we need, will be good for that case.

P.S. yes, you might have different results every single time you run that bench, it's part of the real world ;-)

Monday, September 15, 2014

The Mobile Web Handbook Review

Nobody asked for it, nobody paid me, and I've personally met @ppk no more than once in Warsaw 'cause we both have been speakers at the same conference, but I've kept following him since his beginning with Mobile Web, time that is approximately equivalent to the same I've started with Mobile Web development too.
Beside his well known quirksmode blog, he collaborated with Vodafone, NOKIA, and many others, while I've worked in the meanwhile on Mobile HTML5 NOKIA Maps, for a short time at Mobile Facebook site as well as Mobile Twitter site for the last couple of years so ... we both kinda come from the same multitude of devices, OSs, immature browsers and APIs, passing through the dream and the partial lie behind Mobile HTML5 Development and its ability to replace native.
This review will be somehow short and targeted, but hopefully great for the future of the Mobile Web itself ... uh wait, I've forgot the book name and link: The Mobile Web Handbook

As a Manager, you should read it!

The bold approach of the book is enlightening reaching the point even big corporates are mentioned in all their faults in terms of management and/or focus and/or outdated vision.
As a manager, you can learn how not to loose focus and/or screw up not just your team but potentially the entire company you are working for ... which you know, it's in your best interests!
First couple of chapters would be enough to understand what I am talking about, but being the book not that technical at all, you will learn and enjoy everything else too, or at least its key/core concepts, specially when it comes to write down pros and cons behind HTML5 and the Mobile Web.

As a Web Developer, you should read it!

Specially behind "the must have frameworks or libraries" culture, there are too many developers thinking there is "just one web" and every approach will scale across all platforms and devices ... you have no idea how deadly wrong you could be, and if you have no experience with the Mobile world but you do Web, you inevitably need to learn more from this parallel world because it's so different in all concepts we know and learned online so far, the day you'll have to create something mobile, you don't want to be the last ignorant in the universe that "didn't think about that problem" or believed that, as example, holding everything in RAM 'cause modern laptops have a huge amount of it, it's a good idea that scales out there ... read this book and double check your practices, you might realize there's so much you could actually drop instead of keeping bloating your dependencies!
You've seriously nothing to loose here, only to grow in terms of Web related knowledge, for today or tomorrow devices or just laptops (e.g. do you really know what do you need for a touch screen? Quick hint: no)

As a Mobile Developer, you should read it!

I have to be honest here, being exactly that kind of Mobile Web developer Peter describes in his book, most of the concepts and hints were not new to me but I have learned a lot regardless my experience on basically all mentioned OSs and devices in the book (tons of them, not just the silly Android or iPhone scene).
There are few concept explained behind way deeper analysis that I could have ever thought about, like the one after Who Killed My Battery, a study from Stanford University about how bad could be libraries such jQuery or others for your phone battery life ... I let you read the book in order to understand all takeaways here.

Things I disagreed

The plural is actually too much since there's basically only one concept I don't agree with Peter and it's about Pointer Events. Not only I've written already what I think about them and what's their current state, but Peter himself re-convinced me touch and mouse are completely different beasts, unfortunately struggling later on to counter-proof it makes sense to have both in a single stream ... no, it doesn't, IMO, it's just a mess at the end of the day, due all things you need to take care of inside the stream behind a single "eventname" instead of separating concerns outside it through those meaningful and semantic events. He even ended up suggesting mouseout and mouveover as events a part and beside pointer events, so that he basically described everything I think is wrong with these pointer events themselves! However, he did argument properly his point of view so I'll let you judge by your own the touch VS mouse VS pen VS new iWatch wheel VS ... how screwed is that part of the story.

... and not even that technical

So here the extra, there's no code to follow or test, rather many concepts to understand, learn, and stick in our mind as web developers. The book is an easy read that does not require special skills in HTML5, CSS, or JavaScript, it simply describes problems and solutions in a very pragmatic and documented way.

As summary

The price is not that high at all and if you want to live in 2014 and the future, instead of keep believing dogmas of the old Desktop oriented Web development, I do suggest you to give The Mobile Web Handbook a read: totally worth it!

Wednesday, September 10, 2014

A simple CSS page watermark

This is a very quick one about watermarking a generic website.

via CSS only

Add the following snippet to your CSS and adjust if you want custom properties.
html:after {

  /* common custom values */
  content: "© Water Mark"; /* your site name */
  font-size: 720%;         /* font size */
  color: rgba(0, 0, 0, .1);
  /* alpha, could be even rgba(0,0,0,.05) */

  /* rest of the logic */
  z-index: 9999;
  cursor: default;
  display: block;
  position: fixed;
  top: 33%;
  right: 0;
  bottom: 0;
  left: 15%;
  font-family: sans-serif;
  font-weight: bold;
  font-style: italic;
  text-align: center;
  line-height: 100%;

  /* not sure about who implemented what ..
    ... so bring it all */
  -webkit-pointer-events: none;
  -moz-pointer-events: none;
  -ms-pointer-events: none;
  -o-pointer-events: none;
  pointer-events: none;

  -webkit-transform: rotate(-45deg);
  -moz-transform: rotate(-45deg);
  -ms-transform: rotate(-45deg);
  -o-transform: rotate(-45deg);
  transform: rotate(-45deg);

  -webkit-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  -o-user-select: none;
  user-select: none;
}

via restyle({}) at runtime

Place restyle.js in scope, then:
restyle({
  'html:after': {

    /* common custom values */
    content: '"© Water Mark"',  /* show what ? */
    fontSize: '720%',           /* how big ? */
    color: 'rgba(0, 0, 0, .1)', /* how visible ? */

    /* rest of the logic */
    zIndex: '9999',
    cursor: 'default',
    display: 'block',
    position: 'fixed',
    top: '33%',
    right: 0,
    bottom: 0,
    left: '15%',
    fontFamily: 'sans-serif',
    fontWeight: 'bold',
    fontStyle: 'italic',
    textAlign: 'center',
    lineHeight: '100%',
    pointerEvents: 'none',
    transform: 'rotate(-45deg)',
    userSelect: 'none'
  }
});
I've quickly tested this even on Google Maps and it worked like a charm and I don't know yet how many browsers will support this CSS approach but it seems that all modern browsers are just fine.
Enjoy

Sunday, August 17, 2014

Self contained Custom Elements via restyle()

There is an ongoing discussion about import link for both dependencies and Web Components, here my quick take on it: drop them! Just trash the fluff and use the DOM, it's freaking awesome these days and it works in every browser, you will rarely regret this choice!

However ...

Some dependency could be given for granted, which is actually the best we could do in order to simplify the mess (i.e. you use jQuery all over, don't include it in your file, assume it's there and mark it explicitly as must have in your component documentation).
Be sure that polyfills and/or dependencies are loaded upfront, which also means you should forget about async and other tricks if you want to rely these libraries are in.

restyle() and Custom Elements

Assuming this tiny library is in place, slightly more than just 1KB once minified and gzipped in its latest version, you might end up being able to confine the entire custom element behavior in just a javascript file. Have a look at this demo, based on same CSS and mostly same JS used in this post.
Yes, you got it right, custom elements are entirely confined in a single JS file.

A little helper for huge results!

The changes I've made in restyle are basically components oriented so that it's now possible to automatically confine some CSS inside a rule:
var style = restyle('my-element', {
  div: {
    border: '1px solid black'
  },
  i: {display: 'none'}
});

// will result in 
my-element div {
  border: 1px solid black;
}
my-element i {
  display: none;
}
Having somehow "sandboxed" all nodes also simplify the concept behind any Shadow Dom, except it works today with all browsers compatible with my document.registerElement and restyle code, basically all browsers you can think of except IE8 due Custom Element limits in this browser.

As Summary

Using little tools like restyle could give us the opportunity to use today Custom Elements without needing to wait a universally good, fast, and reliable solution via HTML5 imports combined with ES6 too, we can already place in a semantically similar way CSS into JS thanks to restyle and via JS also solve dependencies when appropriate. Feel free to play with the freshly new version of restyle and please don't hesitate to file bugs or suggest improvements: these are early days for Custom Elements and Web Components, this is the right time to nail it right!

Saturday, August 16, 2014

PointerEvents No More

It is stated and reasoned in this bug related comment that PointerEvents will not land in Blink, the Chrome/ium DOM related engine.
The brief summary, from the technical point of view, is the following:
  1. Touch events already demonstrated to work on the Mobile Web, no need to have more complex and, for mobile Web purpose, redundant API
  2. The hit-test model proposed by PointerEvents will penalize performance. Being such model not even available in Android or iOS it makes no sense to further penalize the Web against native.
  3. More complexity but less power, since it's not possible to intercept touch move while scrolling an element, being PointerEvents and scrolling mutually exclusive.
There are other reasons in the related thread and one of most important sentence, in my opinion, is summarized here:
The main shift in thinking for us has been from a position of a desktop-dominated web evolving slowly to enable mobile scenarios, to the realization that phones/tablets will soon dominate Internet usage and that the web is loosing to native mobile platforms.

Where PointerEvents failed

This is the most important argument against PointerEvents: touch capable Mobile Web has been around for 6+ years now and that Hardware still works properly with modern websites. Having 2 ways to end up dealing in the same exact way touch actions is redundant/duplicated code nobody wants to implement for a Mobile interface.

more complexity to do the same thing

If you have some experience with PoitnerEvents you know you ended up writing code like this:
// Handler => https://gist.github.com/WebReflection/9814013
// just a basic utility to simplify events managment
Handler.add(node, {
  // simulating touchstart and mousedown
  pointerdown: function (e) {
    if (e.pointerType == 'touch' ||
        e.pointerType == e.MSPOINTER_TYPE_TOUCH) {
      e.currentTarget.setPointerCapture(e.pointerId);
      e.preventDefault();
      // now prepare to move
    } else if(e.pointerType == 'mouse') {
      // mousedown, maybe start dragging?
    }
  },
  // simulating touchmove and mousemove
  pointermove: function (e) {
    if (e.pointerType == 'touch' ||
        e.pointerType == e.MSPOINTER_TYPE_TOUCH) {
      e.preventDefault();
      // do the touchmove like thing
    } else if(e.pointerType == 'mouse') {
      // mousemove, drag
    }
  },
  // simulating touchend
  pointerup: function (e) {
    if (e.pointerType == 'touch' ||
        e.pointerType == e.MSPOINTER_TYPE_TOUCH) {
      e.currentTarget.releasePointerCapture(e.pointerId);
      e.preventDefault();
      // clear state
    } else if(e.pointerType == 'mouse') {
      // mouseup, stop drag
    }
  },

  // for backward compatibility
  _fixed: function(e, method, pointerType) {
    e.setPointerCapture = e.msSetPointerCapture;
    return e;
  },
  MSPointerDown: function (e) {
    this.pointerdown(this._fixed(e));
  },
  MSPointerMove: function (e) {
    this.pointermove(this._fixed(e));
  },
  MSPointerUp: function (e) {
    this.pointerup(this._fixed(e));
  }
});
Not only we have coupled different meaning into a single stream of events, inevitably messing up readability and merging concerns because of different behaviors, but what we basically did on touch side is reflecting exactly this logic:
Handler.add(node, {
  touchstart: function (e) {
    // to also avoid dispatched mouse listeners
    e.preventDefault();
    // prepare to move
  },
  touchmove: function (e) {
    e.preventDefault();
    // do the touchmove thing
  },
  touchend: function (e) {
    e.preventDefault();
    // clear state
  }
});
If we want to also implement mouse events, how about doing in the universally compatible way we all know since 90s ?
Handler.add(node, {
  mousedown: function (e) {
    // prepare for dragging
  },
  mousemove: function (e) {
    // drag
  },
  mouseup: function (e) {
    // drop
  }
});
How cleaner is the code we all understand, write, and read compared with the PointerEvents counterpart?

no reliable polyfills

Despite the amount of attempts out there, setPointerCapture is implicitly invoked by default in every Touch based device. This basically means that unless that polyfill takes over the entire DOM interaction, killing performance already problematic even if implemented natively also due that hit-test target mentioned at the beginning, there is no way to have the exact same, default, behavior IE10 or IE11 implement.
This is not true the other way round, we can use PointerEvents to simulate Touch as shown before acting by default like them.
// demo only; don't use this code in prod!
Handler.add(node, {
  touchstart: function (e) {
    // prepare for move
  },
  touchmove: function (e) {
    // move
  },
  touchend: function (e) {
    // that's it
  },

  // use IE events to simulate touch
  pointerdown: function (e) {
    if (e.pointerType == 'touch') {
      e.currentTarget.setPointerCapture(e.pointerId);
      e.touchlist = [e];
      this.touchstart(e);
    }
  }

});
Luckily we don't have to take care about this mess, we should just use touch events that finally landed in IE11 Update 1 and eventually, if strictly necessary, we can put upfront a polyfill like ie-touch until all Windows Phone will get the update 1 installed (AFAIK this should happen around the end of August or beginning of September).

Tablet or Desktop ?

If we want to support special or different behaviors between touch and mouse we can simply split the logic and better organize it as shown before. Basically, instead of doing this per each bloody event:
node.addEventListener('pointerdown', function (e) {
  switch(e.pointerType) {
    case 'touch':
    case 'pen':
    case e.MSPOINTER_TYPE_TOUCH:
    case e.MSPOINTER_TYPE_PEN:
      // do touch things
      break;
    case 'mouse':
    case e.MSPOINTER_TYPE_MOUSE:
      // do mouse things
      break;
  }
});
We do this + that:
node.addEventListener('touchstart', function (e) {
  // finger or pen
});
node.addEventListener('mousedown', function (e) {
  // mouse indeed
});
This will also avoid O(n) checks multiplied by every input device event that will trigger on the browser.

So no "pen" anymore ?

I think pen is rather OK as touch device and it's in this event that I'd implement eventually pressure and angle for a simplified graceful enhancement over incompatible old systems that still will work as regular touch events.

Very different worlds

About Table VS Desktop there is another basic concept to consider: nobody drags with touch events, everyone drags with mouse. This is a fundamental split logic we should not underestimate. With touch screens we swipe, spread, pinch, tap, double tap, longpress to action while we right click instead or just point and click, or double click, with possible drag. Accordingly, The only event that has similar intent is click, irony wants that such event already works as expected with every device ... put in click what should have a click behavior, do not merge together any other gesture or intent into a single stream if you don't want to end up with spaghetti listeners hell.

In a nutshell

The initial idea behind PointerEvents was great but it was already showing how confined in an old mouse based world it was. Having all sort of events that might or might not be fired, just consider pointerover that won't happen the way we imagine if we touch the screen, was making the API itself inconsistent with developer expectations.
Moving the problem from a proper listener name, touch or mouse, into a pointerType event property hasn't solved a thing, hasn't worked as expected, hasn't improved performance, hasn't made the code easier to maintain or write ... it messed up listeners instead, adding extra complexity or unexpected default behaviors (i.e. the NON capture for touch events unshimmable as it is) where all we'll end up doing, as developers, is to simplify the logic down to what is possible already with Touch events.

This is Great!

I would like to underline that having specs like that and having played around even in production with those specs has been a great way to evaluate how nicely implemented, or how much troublesome, would these specs have been.
Seeing Microsoft recognizing it was important to support what devs wrote already and what mobile web is these days, bringing Touch events into IE11 Update 1, has been a very welcome and nice move we should all thank them about.
This is the web I like, where instead of silly pointless and endless discussions, we can go down to the concrete and not at all costs stubborn de-facto solution that everyone already used and is happy with and eventually change, or add, something documented and easy to use instead of playing "who's got the lauder voice".
Thanks to all people that helped with PointerEvents and their failure, now please let's make Touch and TouchList as cross platform as possible, including all micro gotchas with preventDefault and scrolling behaviors.

Thursday, August 14, 2014

Can we please stop moaning ?

OK here's the catch: software development is not something I do just for living, it's a passion I have since literarily ever and here's the story.
I'm absolutely envious of modern kids able to put their hands on a Raspberry PI, as example, and develop with Python, nodejs, or pretty much any other programming language available these days using an affordable board that does not need a music-cassette like player and at least half minute of potential personal epileptic attack with multi colors on screen plus noise before being able to show you something on the same screen (yes, I come from Commodore 64 era, a platform I couldn't afford at that time, and yet I feel lucky for owning a MSX and developing/experimenting on it via QBasic when I was between 8 and 11 ... then I've met by accident an Olivetti PC and it has been love since!).

Being greedy about learning!

When in 1998 I've finished high-school in Italy there was not a single University in the entire country that was even "10 years after" close to prepare people for real-world about the World Wide Web.
Those days, and bear in mind this is still the current situation in many "modern" Universities, Computer Science studies were only about some C, Java, or DBRM basics and nothing else; possibly even with an obsolete or deprecated versions of Java itself, nothing like nashorn these days, and just to shout one example.
All I could do in that scenario in order to prepare myself and learn about the Web, was to go online and study by my own everything available on the Internet!
All of this beside some unrelated University class that supposed to give me basis about programming (it kinda didn't for what I needed, it was too early to pretend to teach me Web in Italy at that time) ... guess what, I never completed that course or the one I've done few years after 'cause I was already ways ahead of them at that time.

However, I've been spending my career giving back to the Internet what I've learned contributing with Web specifications, ES specifications, creating libraries, or contributing to them ... this is me, online, today, and since ever!

.. and learning, and learning ...

Back in those days, every time I mastered some topic, another one was coming up harder to understand, harder to find proper online documentation, something we take for granted these days, and harder due concrete lack of time: I was a full time employee already and I needed to work because my studies were not cheap at all and internet was not cheap too, and in order to have a better connection I had to pay extra so that dual channel ISDN could have been possible and I could surf at the amazing speed of 128Kbps in download and 64Kbps in upload!
You read that right: 128 Kilobits per seconds, enough to also feel some sort of realtime zero-lag connection on Quake 3 Arena, a game part of my history too, and more than that, an inspiration about what's possible online even with very low bandwidth connections!
Anyway, my will to learn software and improve daily my skills was at its highest peaks, probably because it was the beginning of my career, most likely and also because it is still required, if you want to survive and be a good, updated, developer at any time in the SW history, to know what's going on around and where Software and Hardware are heading these days, your days, whenever you are reading this!
In few words Welcome to Software Development, nothing like you learn VBScript at Uni or at work once and you are good forever in your lifetime with your job ... if that's what were you looking for, I think I've bad news for you ...

Are *You* willing to learn ?

Apparently in modern software development, and somehow specially in one of the easiest out there, JavaScript development, the worst "curse" ever or the most used example about how hard is to be a software developer is represented by a tilde, a single ~ char apparently full of shame because developers don't understand what it means ... well, I don't want to start swearing randomly here, so I'll try to be calm and explain ...

As easy as this

The only possible falsy value in JS with a tilde, is the number -1 .. repeat with me:
the only falsy value with a tilde is -1
the only falsy value with a tilde is -1
the only falsy value with a tilde is -1

~(-1) === 0; // true
~(-1) == false; // true
Say that 3 times and Crockford will appear on the mirror!
Jokes a part, what does it mean? It simply means that every JavaScript method that returns -1 instead of a boolean false PHP style over a search, or an indexOf is performed over a string or an Array will result falsy when checked against the following:
if (~[1,2,3].indexOf(2)) {
  // YES, 2 is there!!!
  // because the result was !== -1
}

if (!~[1,2,3].indexOf(4)) {
  // NO, there's a NOT "!"
  // of course it's NOT there
  // !~ === NOT
  [1,2,3].push(4);
  // metaphorically speaking ... 
}
This is also usually called a semantic operation for the simple reason that:
  • you didn't put a not "!" operator upfront so you expect that to return truthy result
  • in case you did put a not "!" operator upfront, you'll see 99% of the time a arr.push(missingValue) following ...
so what are you exactly complaining about? The funniest thing ever is that people usually ask you to write this instead:
// they tell you not to write this:
if (~[1,2,3].indexOf(2)) {
  // yeah, it's there
}

// but to write this:
if ([1,2,3].indexOf(2) !== -1) {
  // yeah, it's there
}
Today you must have realized that comparing against !== -1 is the exact equivalent of verifying that the result was not -1 via tilde, because once again: only -1 is falsy after a tilde so indexOf result is truthy only when it's !== -1!

And this is not about being smart

It's rather about learning that some language does not use only +, -, *, and / operators as they taught us at elementary school ... the language has more and you should know more about the language you develop and work with instead of going "I don't understand! OMG, why is that and what it does" first time you see a different operator ... long story short: are you still willing to learn?
'cause next thing you gonna have problems with wil most likely be the proposed power operator, for all those times you didn't want to use Math.pow(num, radix) and you'll find handy to do x**radix instead ... uh wait, you don't know that symbol, it must be evil and/or smart, right?
What are you saying? Python did that before so it's OK? Then you learned something new anyway about the tilde today and in JavaScript, you should actually be happy if that's the case instead of moaning about it?

Not only the tilde

I've been working for many small, medium, and big companies, and the constant scenario is that someone, at some point, will mention sentences like the following one:
I had a problem and I decided to use regular expressions to solve it, so now I have two problems ...
... of course you have two problems if you don't understand regular expressions or you didn't think enough if that was the right case to use them ... here the simple proof: do this in a more efficient way (didn't mention easier, shorter, faster for argument sake but you know it):
function dropA(str) {
  return str.replace(/a/ig, '');
}

// later on in dante.js ...
dropA(divineComedy);
I am waiting here to see how better, faster, shorter, etc plus absolutely not error prone your logic avoided regular expressions ...

Master them instead

Yes, some dev probably does not know, need, or understand, regular expressions, and this is OK, as long as they are not trying at all costs to avoid them!
That would be the most unproductive, error prone, slower, and stubborn approach for a single or a team in case they do not just understand regular expressions ... I mean: no fucking body understand them after born, we all had to learn them so you can continue with your argument about "having two problems" but actually unless you really know regexp you should be the last one to complain about them.

back to tilde

Yes, if you are that good that not only you managed to successfully copy and paste some code that used a tilde but you actually investigated about its meaning in binary terms, you'll also realize that when an Array might contain a huge number of items that could grow unexpectedly, tilde is not what you are looking for *but* only in that case, even if we all like to dream our code will be used up to Math.pow(2, 32) times per each Array we create.

Long story short, if this is your problem, you are actually lucky you never had to deal with WebGL so far, because trust me tilde it's going to be the very last thing you could complain about if all this is about "things you just don't understand"! ( GLES wizardry! )

About the "copy and paste" tribe

Many times I've seen people demanding, complaining, insulting, after some code they copied and pasted from Stack Overflow or any other slightly CS related forum ... I wish we could consider these kind of persons outside the actual Software Developer circle and happily ignore them instead of promoting "write dumb to rule them all" articles all over?
How about we keep promoting Software for everyone to jump in and start ignoring or ditching people that are indirectly ruining this beautiful sector full of research, sometimes sacrifices, and luckily still most of the time: passion?

About daily tasks

When it comes to code reviews and developers that actually know what are doing, I also suggest to go easy with nitpicks because I've realized in my career nitpicks are so light and pointless in a product lifecycle that could only waste time for the product growth instead of actually helping code quality.
As example, if a Senior SW Engineer in your team writes:
if (!worked) return;
instead of:
if (!worked) {
    return;
}
without the JShint even complaining, that is fine and you should probably think about how many minutes, or hours, these silly things, when everyone absolutely understand in first place what's going on with the code, have been wasted just to nitpick stuff that for new comers, might actually be a chance to better learn what they are doing, instead of letting them think brackets solved the world ... of course they did when no tests were in place, if that's your only argument because something bad unrelated with brackets happened before :P

As summary

Please respect SW Developers and, if you consider that your job, respect yourself too.
So please let's all moaning less about basic SW Development concepts ... let's all talk about how to improve what's working already instead of how to welcome new copy and paste people.


Thank You!