Multiple people asked what's the story about JSX and CoffeeScript. There is no JSX pre-processor for CoffeeScript and I'm not aware of anyone working on it. (If you are interested in writing one, you probably should look at CoffeeScriptRedux). Fortunately, CoffeeScript is pretty expressive and we can play around the syntax to come up with something that is usable.

Example

Let's see how JSX look like with an example:

<div classname="MarkdownEditor">
 
 
<h3>Input</h3>
 
 
  <textarea onkeyup="{this.handleKeyUp}" ref="textarea">    {this.state.value}
  </textarea>
</div>

which desugars to the following

React.DOM.div({className: 'MarkdownEditor'}, [
  React.DOM.h3({}, 'Input'),
  React.DOM.textarea({onKeyUp: this.handleKeyUp, ref: 'textarea'},
    this.state.value
  )
])

We can easily translate it to CoffeeScript:

{div, h3, textarea} = React.DOM
(div {className: 'MarkdownEditor'}, [
  (h3 {}, 'Input'),
  (textarea {onKeyUp: @handleKeyUp, ref: 'textarea'},
    @state.value
  )
])

Structure

The translations rules are really easy. The only gotcha is to write the tags wrapped in parenthesis lisp-style. This is the best way I found not to get caught with indentation issues.

# Empty element
#
 
 
<div></div>
 
 
 
(div {})
 
# Text children: You use a string literal
#
 
 
<div>foo</div>
 
 
 
(div {}, 'foo')
 
# Interpolation: You ignore the {} and write the expression as is
#
 
 
<div>{this.state.text}</div>
 
 
 
(div {}, @state.text)
 
# Multiple children: You use the [] notation
#
 
 
<div>
  <b r="">
  <b r="">
</b></b></div>
<b r=""><b r="">
 
 
(div {}, [
  (br {}),
  (br {})
])
 
# Attributes: You write them using {} notation
#
 
 
<div onclick="{this.onClick}"></div>
 
 
 
(div {onClick: @onClick})
</b></b>

Demos

I've re-written all the React front-page examples using CoffeeScript. The translation was really easy.

Hello World

Timer

Todo

Markdown

Using x-tags from Mozilla, we can write custom tags within the DOM. This is a great opportunity to be able to write reusable components without being tied to a particular library. I wrote x-react to have them being rendered in React.

Example

We're first going to write a regular React component.

var Hello = React.createClass({
  render: function() { return <div>{'Hello ' + this.props.name}</div>; }
});

Then, we use xreact.register to bind a React component to a custom tag name.

xreact.register('x-hello', Hello);

At this point, any DOM element will be rendered using React.

<x-hello name="World"></x-hello>

The rendered DOM tree lives in the shadow DOM. This lets us manipulate both the component as well as the rendered <div> using Web Inspector.

Anytime you modify the component, whether it is in the inspector or in Javascript with the regular DOM API, React is going to be invoked to update the rendered version.

Behind the scenes

When you call xreact.register, we call xtag.register saying that whenever an DOM element is created, we render a special component called XReact in the shadow root of <x-hello>.

xtag.register('x-hello', {
  lifecycle: {
    created: function() {
      React.renderComponent(
        XReact({element: this}),
        this.createShadowRoot()
      );
    }
  }
});

XReact is a really simple component that takes a DOM node, in this case <x-hello name="World" /> and converts it to the React equivalent: Hello({name: 'World'}).

var XReact = React.createClass({
  render: function() {
    return convertDOMToReact(this.props.element);
  }

MutationObserver gives us a callback whenever the DOM element is changed. We just have to call this.forceUpdate() to make sure the React rendered version stays in sync.

  componentDidMount: function() {
    new MutationObserver(this.forceUpdate.bind(this)).observe(
      this.props.element, {/* all the possible mutations */}
    );
  }
);

That's it 🙂

Conclusion

It was really easy to make this small bridge in order to be able to create custom tags and have them rendered using React. Unfortunately, this experiment is only working on Chrome as it is relying on MutationObserver and Shadow DOM.

In 2001, Douglas Crockford evangelized private members design pattern and since then has been widely adopted by the Javascript community. However, are they really private?

Javascript is an extremely dynamic language in which it is possible to access a lot of things on way or another. We'll see how to get a reference to most of the "private" methods you can find in the wild.

Example

Here's a snippet of code from underscore.js. We are interested in getting a reference to the following "private" functions: lookupIterator and group.

(function() {
  /* ... */
 
  // An internal function to generate lookup iterators.
  var lookupIterator = function(value) {
    return _.isFunction(value) ? value : function(obj){ return obj[value]; };
  };
 
  // An internal function used for aggregate "group by" operations.
  var group = function(obj, value, context, behavior) {
    var result = {};
    var iterator = lookupIterator(value || _.identity);
    each(obj, function(value, index) {
      var key = iterator.call(context, value, index, obj);
      behavior(result, key, value);
    });
    return result;
  };
 
  // Groups the object's values by a criterion. Pass either a string attribute
  // to group by, or a function that returns the criterion.
  _.groupBy = function(obj, value, context) {
    return group(obj, value, context, function(result, key, value) {
      (_.has(result, key) ? result[key] : (result[key] = [])).push(value);
    });
  };
 
  /* ... */
}).call(this);

Here's the code to do it: (Demo on JSFiddle)

var lookupIterator;
var group;
 
_.isFunction = function() {
  lookupIterator = arguments.callee.caller;
  group = lookupIterator.caller;
};
_.groupBy();
 
console.log('lookupIterator', lookupIterator);
console.log('group', group);

The way it works is by hooking a function deep inside the internals of the module you want to break into and use arguments.callee.caller to get references to all the functions upward.

In this case, it was easy as we could hook _.isFunction. You can break into a lot of functions overriding String.prototype and using __defineGetter__.

Conclusion

Trying to break into existing Javascript code and make it do what you want is an extremely fun exercise. If this topic is of interest to you, take a look at this big list of Javascript attack vectors written by Google Caja team.

Daniel Baulig, a co-worker at Facebook, told me a little trick related to jDataView function to convert from a uint8 to a int8 in Javascript.

Here's the version I had:

function getInt8() {
  var b = this.getUint8();
  if (b > Math.pow(2, 7) - 1) {
    return b - Math.pow(2, 8);
  }
  return b;
}

Compare it to his version:

< <function getInt8() {
  return this.getUint8() << 24 >> 24;
}

I was really confused because it seems like it's doing a no-op. Here's the full explanation of why the two versions are working.

How it works?

The following table (borrowed from Wikipedia) shows how various 8 bits values are in represented with bits and how they are interpreted in unsigned and signed (using two-complement rule).

Bits uint8 int8
0000 0000 0 0
0000 0001 1 1
0000 0010 2 2
0111 1110 126 126
0111 1111 127 127
1000 0000 128 −128
1000 0001 129 −127
1000 0010 130 −126
1111 1110 254 −2
1111 1111 255 −1

Javascript doesn't natively have a 8 bit integer type, it only has a 32 bits one. When you put a 8 bit integer into a 32 bits one, Javascript is going to fill the remaining bits on the left with zeros as the following table shows.

Bits int32
0000 0000 ... 0000 0000 0
0000 0000 ... 0000 0001 1
0000 0000 ... 0000 0010 2
0000 0000 ... 0111 1110 126
0000 0000 ... 0111 1111 127
0000 0000 ... 1000 0000 128
0000 0000 ... 1000 0001 129
0000 0000 ... 1000 0010 130
0000 0000 ... 1111 1110 254
0000 0000 ... 1111 1111 255

Unfortunately, this doesn't properly handle negative numbers. Because we use two-complement, we've got to fill all the bits with 1 for negative numbers in order to have the same number in a signed 32 bits representation.

Bits int32
0000 0000 ... 0000 0000 0
0000 0000 ... 0000 0001 1
0000 0000 ... 0000 0010 2
0000 0000 ... 0111 1110 126
0000 0000 ... 0111 1111 127
1111 1111 ... 1000 0000 −128
1111 1111 ... 1000 0001 −127
1111 1111 ... 1000 0010 −126
1111 1111 ... 1111 1110 −2
1111 1111 ... 1111 1111 −1

So basically, we've got to fill the 24 remaining bits on the left with the same first bit we have: 0 for positive numbers and 1 for negative numbers.

This is when the trick comes into place. In javascript, there's a binary operator: >> Sign-propagating right shift that moves all the bits to the right and fills the missing bits with the first bit.

So all we have to do is to put our 8 good digits to the far left using << and then use the previous trick to fill the bits with the proper ones 🙂

x x < < 24 (x << 24) >> 24
0000 0000 ... 0000 0000 0000 0000 ... 0000 0000 0000 0000 ... 0000 0000
0000 0000 ... 0000 0001 0000 0001 ... 0000 0000 0000 0000 ... 0000 0001
0000 0000 ... 0000 0010 0000 0010 ... 0000 0000 0000 0000 ... 0000 0010
0000 0000 ... 0111 1110 0111 1110 ... 0000 0000 0000 0000 ... 0111 1110
0000 0000 ... 0111 1111 0111 1111 ... 0000 0000 0000 0000 ... 0111 1111
0000 0000 ... 1000 0000 1000 0000 ... 0000 0000 1111 1111 ... 1000 0000
0000 0000 ... 1000 0001 1000 0001 ... 0000 0000 1111 1111 ... 1000 0001
0000 0000 ... 1000 0010 1000 0010 ... 0000 0000 1111 1111 ... 1000 0010
0000 0000 ... 1111 1110 1111 1110 ... 0000 0000 1111 1111 ... 1111 1110
0000 0000 ... 1111 1111 1111 1111 ... 0000 0000 1111 1111 ... 1111 1111

It's often said that XML is very verbose and therefore JSON is better. I wanted to challenge that assumption and find the smallest way to represent any JSON value using XML.

Constants
true
<t/> 0
false
<f/> - 1
null
<l/> 0
Number
NaN
<n/> + 1
123.45
<n>123.45</n>
+ 6
String

""
<s/> + 2
"Abcd"
<s>Abcd</s>
+ 4
Array
[]
<a/> + 2
[1, "two", false]
<a>
  <n>1</n>
  <s>two</s>
  <f></f>
</a>
+ 4 - n
Object
{}
<o/> + 2
{
  "first": 1,
  "second": "two",
  "third": false
}
<o>
  <n k="first">1</n>
  <s k="second">two</s>
  <f k="third"></f>
</o>
+ 5 + n

As you can see, the XML counter part is a bit more verbose and less readable because of the way syntax highlighting is setup. However, while it is bigger, it isn't out of proportion bigger. The structure can be at most twice as big.

Implementation

In order to implement it, I decided to go with the same API as JSON:

  • XSON.stringify(object, formatter, space)
  • XSON.parse(string)

You can play with it on this current page or can check it out on GitHub.

The implementation was more straightforward than I expected thanks to the fact that there's a XML Parser inside browsers. However, I had to deal with nasty encoding issues 🙁

String encoding

There are some characters such as < and \0 that we want to escape because otherwise they are likely to be problematic while parsing the XML. The way to encode those characters in XML is to use the &#number; notation where number is the character code. For example a is represented by a:

> new DOMParser().parseFromString('<a>&#97;</a>', 'text/xml')
    .getElementsByTagName('a')[0].textContent
"a"

Unfortunately, you cannot express all the characters with this notation. The XML specification introduces Restricted Characters in the following ranges: [#x1-#x8], [#xB-#xC], [#xE-#x1F], [#x7F-#x84] and [#x86-#x9F]. When you try to read those characters, then the XML parser generates an error.

> new DOMParser().parseFromString('<a>&#0;</a>', 'text/xml')
    .getElementsByTagName('a')[0].textContent
"error on line 1 at column 8: xmlParseCharRef: invalid xmlChar value 0"

Instead of fighting with the XML spec, I decided to use my own encoding. I replace the character by \u0000. Where the number is an hexadecimal representation of the number padding so it has exactly four digits.

To do that, we need first to escape all the \ and can use a regex to do it in few lines of code 🙂

function encode(str) {
   return str
     .replace(/\\/g, '\\\\')
     .replace(/[\u0000-\u0008\u000b-\u001f&<>"\n\t]/g, function(c) {
       var hex = c.charCodeAt(0).toString(16);
       while (hex.length < 4) {
         hex = '0' + hex;
       }
       return '\\u' + hex;
     });
 }

Then, in order to decode it, we do the opposite: we first decode all the unicode characters and remove the escapes. In order to make sure that the unicode character was not escape, I'm using a small trick. You can count the number of \. If it's an even number, then it is not escaped, otherwise it is escaped!

function decode(str) {
  return str
    .replace(/(\\*)\\u([0-9a-f]{4})/g, function(match, backslash, n) {
      if (backslash.length % 2 !== 0) {
        return match;
      }
      return backslash + String.fromCharCode(parseInt(n, 16));
    })
    .replace(/\\\\/g, '\\');
}