angular/angular.js — pull request #7700 by rodyhaddad (2014-06-04 22:31:19+00:00)
Title: perf(*): more performant interpolation and lazy one-time binding

This PR implements a different approach to one-time binding, which also gives us a performant improvement for $interpolate by about 33%.

Here's a benchmark app using the current snapshot: [plunkr](http://plnkr.co/edit/ED75f0qo0gnvodl9rCDV?p=preview)
Here's the same benchmark with this PR: [plunkr](http://plnkr.co/edit/PbzTM5IviKydEH2dXfFZ?p=preview)

Look at the difference between the two `baseline interpolation`. It goes from 30-35ms to 20-25ms.
This gets us closer the the `baseline binding`, which is about 15-20ms.
The other 3 benchmarks in the benchmark app remain unchanged.

## What's behind this change:

### Expressions can say how they want to be watched
This allows the following:
* Given `interFn = $interpolate('{{a}}{{b}}')`, interFn can say that it wants to be watched by: watching each expression individually (i.e. `scope.$watchGroup(['a', 'b']`)
* Given `parseFn = $parse('1 + 1')`, parseFn can say that it wants to be watched by: getting evaluated on the next $digest, and then unregistering itself since its constant anyway
* Given `parseFn = $parse('::foo')`, parseFn can say that it wants to be watched by: getting evaluated on the $digest as usual, and unregistering itself when its value is no longer `undefined` (a.k.a. bind-once)

### InterceptionFn
There are cases where the last scenario doesn't work out as we'd like.
If we're watching a function that calls `parseFn` inside it, we lose the benefits mentioned above. That's because `parseFn` isn't aware that it's being watched (indirectly). So I created an _interceptorFn_ in `$parse` that goes around this issue. Interceptors work as filters and you can easily see their application in ngBind.js or sce.js

-----

I could go into more details, but you should check the code.
The first commit just reverts the current implementation of bind-once, so checking the second commit on it's own can make reviewing easier
Suggested order of review:
- rootScope.js
- interpolate.js
- parse.js
- The rest