My JavaScript book is out! Don't miss the opportunity to upgrade your beginner or average dev skills.

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!

Sunday, August 10, 2014

Auto instance via "use strict"

This is a very simple trick that works if you are sure your minifier will not remove any 'use strict' declarations in your scripts.

As seen in jQuery

This library is the most known/common example where $(something) will actually generate an instanceof jQuery variable even without using new.

Some background

Since basically ever, JavaScript constructors such Array, Object, Function and RegExp do not distinguish between new Array/Object/Function/RegExp or just the same without new, and there are exceptions for Date, where it always returns the same instance if invoked without new, and primitives wrappers such Boolean, Number, or String, where the meaning is very different: it's casting VS value wrapper when new is used.
This behavior could be somehow desired when we'd like to obtain the exact same return type when a generic constructor is invoked either via new or not.

Handy "use strict"

Because of its guard against the execution context, where this would be undefined instead of the global window object, we can use such behavior to simplify the famous pattern.
// basic use strict feature
function Constructor() {'use strict';
  return this || new Constructor;
}
This is basically the easiest way to replicate this pre-use-strict era pattern:
function Constructor() {
  return this instanceof Constructor ?
    this : new Constructor
  ;
}
The benchmark shows no impact on Safari, but quite a gap between the old and the new pattern in Chrome. Good news is, who cares, the trick is to write less and reduce code size so if it's even faster, it's just a strawberry on top.

A different behavior

In case somebody will use Constructor.call(anotherObject) the instance will be used inside the constructor instead of being ignored via good old pattern.
This is actually not necessarily an undesired side effect because it actually lets us reuse constructors to initialize properties with mixins too, in case the initializzation is needed.
// old pattern ...
function Constructor(value) {
  if (!(this instanceof Constructor)) {
    return new Constructor(value);
  }
  this.property = value;
}

// later on ...
var mixedObject = {};
Constructor.call(mixedObject, 123);
mixedObject.property; // undefined
Using initial pattern we basically do nothing except creating a new instance that will be lost in the process while with the pattern suggested via use strict things play nicer than before!
// use strict
function Constructor(value) {'use strict';
  if (!this) return new Constructor(value);
  this.property = value;
}

// later on ...
var mixedObject = {};
Constructor.call(mixedObject, 123);
mixedObject.property; // 123 <=== yeah!

No backward compatible!

As easy as that, in order to be able to use this pattern the engine must be compatible with use strict directive, which is actually not a big deal in nodejs or other modern server side engines, as well as most common browsers targeted for mobile apps or extensions.
In case you don't know about some target, do you remember the trick to know if the JS engine is compatible?
var hasUseStrict = (function(){'use strict';return!this}());
Please note that use strict brings other features too so be sure other behaviors won't affect your code logic.

Wait ... what about arguments?

There are two scenarios here, the one when it does not matter:
// use strict
function Constructor(a, b, c) {'use strict';
  if (!this) return new Constructor(a, b, c);
  // go on ... 
}
and the one where exact number of arguments matter:
// use strict
function Constructor(a, b, c) {'use strict';
  if (!this) {
    return Constructor.apply(
      Object.create(Constructor.prototype),
      arguments
    );
  }
  // go on ... 
}
Take care