Revert the new feature that all helpers in enclosing templates are visible, including helpers on the template that called the current template (for example) and helpers on UI.body.
Making helpers visible to sub-templates was a major change that was never properly justified or thought through. Helpers take precedence over data properties, and having helpers "leak" down through the app could have bad consequences, even if it's useful for defining helpers on a group of related templates. There was a point in shark's history where we needed this dynamic lookup in order for helpers to work in block tags, but that's no longer the case.
Now, helpers are only visible to the lexical body of the template they are defined on (except for global helpers defined with UI.registerHelper).
Ran tests in Chrome; ran todos and docs.
findAll was always supposed to return a jQuery object if you use jQuery (which is always at the moment).
Now `this.$` is an alias for `this.findAll`, as well.
in template helpers and event handlers. 'this' must be an object and
it can't be null, so an empty object is the best we can do (and surely
better than 'window' which is what we had before this commit)
This was a regression from Spark.
We now no longer check whether we're at a closing
HTML tag by peeking for "</" since that would fail
if there were a {{! }} comment directly before it.
Instead, we tokenize and then rewind. Presumably
this does have an effect on compilation time but it's
probably fine. An alternative would have been to
explicitly parse {{! }} comments rather than implicitly
skipping them before generally parsing tokens.
The implementation is getting really, really ugly. Just want to get to correctness.
We now stop autoruns not just when started from `materialize` but also `toHTML`, `toText`, and `evaluate`, which is important for HTML attributes. Reactive regions inside attributes aren't individually autorun; the design is that their dependencies will cause the entire attribute updater to be invalidated and re-run. In other words, HTML.toText doesn't have internal re-runs but it does register dependencies on the current computation. In fact, however, the presence of emboxedValues means that there *are* autoruns that need to be stopped, even in toText and evaluate.
The hack where we define a `.materialized()` callback for the benefit of UI.With falls short, because toText et al. don't call it. The current workaround is yet worse hacks in htmljs (stopWithLater).
Finally, the fact that UI.If, UI.Unless, and Spacebars.include return reactive closures that close over emboxedValues is a problem when those same closures are reused in recalculating attributes. The intent was that recalculating attributes should tear down any boxes internal to the attribute calculation and start fresh, but when we reuse closures that close over boxes, we are reusing boxes, and if those boxes have been stopped we lose correctness. The ugly hack to get this to work for now is to have the boxes in If, Unless and include not be per reactive closure but per currentComputation, i.e. per autorun. Since toText et al. don't normally autorun reactive closures, we add an autorun so that they get their own Computation objects. This hack is supported by UI.namedEmboxValue and callReactiveFunction.
The good news is that the right answer is buried in here somewhere.
Now you can actually see function source code when you inspect _onInvalidateCallbacks in the debugger. Instead of wrapping a bunch of stuff around the callbacks before enqueuing them, we move the logic to where they are called.
That gives us enough guarantees that we can simplify the error-handling
code.
We also ensure that the "new connection" handler in livedata_server runs
in a Fiber, which fixes a bug introduced in d049bf7506 where connections
from pre-pre1 clients would crash (due to Meteor.setTimeout which only
works in a Fiber).
Unfortunately, using it always led to reactive functions
firing twice. Instead, we now use emboxValue in the two
cases we originally had Deps.isolateValue.
If we want the *internal* state of the oplog driver to be consistent, we
need to make sure that we start our observes at a consistent point in
the oplog. (ie, initial inserts need to have been fully processed, so
that we don't process them during the original QUERYING phase, which can
give us a different unpublished buffer.)
Note that only the white-box tests (looked at _unpublishedBuffer, eg)
appeared to be flaky: the actual docs published seemed to be correct in
all cases.