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

Monday, February 10, 2014

trapping an ES6 Proxy inside a with statement

restyle.js from Andrea Giammarchi on Vimeo.

update 2 to play with(restyle.properties){...} having a closure for variables and functions ... here an example ;-)

update I've been putting together explained ideas in both Proxy and a restyle.properties version that should work already in every ES5 capable environment.
Both files share the same alpha utilities file that can and will be enriched from time to time!
You can test current status directly in this page and you can also click the parsed area to have a link to share.
See how natural it feels? .. Now, imagine all browser prefixes are automagically added and you could also write around functions and variables to reuse code as you can already do in restyle ;-)
enjoy
too good and too powerful to be left ignored as pattern, while testing handy ways to make web developers life easier with a tool born for that as restyle is, I couldn't stop admiring how powerful is a with statement when a Proxy is passed as argument.

Next Tooling Level

Seriously, have a look at this Proxy:
var CSSProxy = new Proxy(
  {
    // borrowed from from eddy.js
    // https://github.com/WebReflection/eddy
    boundTo: function (method) {
      return this.$[method] || (
        this.$[method] = this._[method].bind(this)
      );
    },
    // CSS properties that clash with window
    special: /^(?:top|scroll)$/,
    // common camelCase RegExp
    find: /([a-z])([A-Z])/g,
    // common camelCase to camel-case replacement
    replace: function (m, $1, $2) {
      return $1 + '-' + $2.toLowerCase();
    },
    // a collection of already bound methods
    // it avoids blowed RAM for no reason
    // as eddy.js boundTo method does by default
    $: {},
    // the target.utility namespace
    _: {
      // in this case an hex example
      hex: function (r, g, b) {
        return '#'.concat(
          ('0' + r.toString(16)).slice(-2),
          ('0' + g.toString(16)).slice(-2),
          ('0' + b.toString(16)).slice(-2)
        );
      },
      // to write directly url('path.ext')
      url: function(src) {
        return 'url("' + src + '");'
      }
    }
  },
  // the proxy
  {
    // inside a with, everything that is not there
    // will be checked here
    has: function (target, name) {
      return  window.hasOwnProperty(name) ?
          target.special.test(name) : true;
    },
    // when .has(name) returns true ...
    get: function (target, name, receiver) {
      // either it's a method from here
      return target._.hasOwnProperty(name) ?
        // and it should be bound
        target.boundTo(name) :
        // or is a value name
        name.replace(
          target.find,
          target.replace
        );
    }
  }
);

The What And The How

Imagine you are writing through JS some CSS property for a server side/node.js pre-processor ...
with (CSSProxy) {
  console.log({
    // r, g, b to HEX value
    color: hex(100, 50, 150),   // #643296
    textAlign: center,          // 'center'
    backgroundRepeat: noRepeat, // 'no-repeat'
    content: noCloseQuote       // 'no-close-quote'
  });
}
Now, combine this with restyle(object) power:
with (CSSProxy) {
  var myApp = restyle({
    'html, body': {
      color: red,
      background: {
        image: url("image.png"),
        color: black,
        position: top
      }
    },
    section: {
      overflow: hidden,
      display: block,
    
    }
  });
}
Now, I don't know what you think but I believe this combination kicks every other CSS via JS processor out of the competition!

P.S. yeah, this is freaking cool stuff I am pretty sure somebody will complain about and shut it down as it was already for the awesome with statement :-(
ES3 FTW!

No comments: