lift/framework — pull request #1585 by Shadowfiend (2014-06-20 04:26:06+00:00)
Title: Fiery Comets: Support for AJAX responses with comets

This is #1565 reopened with respect to `master`.

To support AJAX responses that send down comets, this PR actually
refactors a few aspects of comet creation:
- `LiftSession` now has a new internal (private) API for finding or creating
a comet. There are two variations of `findOrCreateComet`, one that takes
a type parameter (`findOrCreateComet[MyCometType](name, html, attributes)`)
and one that takes a string comet type (`findOrCreateComet("MyCometType", ...)`)
The type parameter version uses manifests to allow direct instantiation of a
comet without reflection overhead and without requiring the comet to be in the
regular comet package if not wanted.
- `LiftSession`'s comet-related code has been significantly refactored to
eliminate duplication and make things a little easier to follow. Notably, there
are still some anonymous subclasses of `CometActor` created for round-trips
and streaming promises; those will be refactored to independent subclasses
at some point, but I didn't do it in this PR.
- Comet ID info (type + name) now has a (private) case class `CometId` to represent
it in `LiftSession`.
- The `CometCreationInfo` case class, which was in the `Templates.scala` file, is
now in the `CometActor.scala` file, and is used pervasively to pass comet creation
info around (before, we were using separate parameters in many places). This is
still mostly an internal class, however.
- Publicly, `S` has a new API for finding or creating a comet, `S.findOrCreateComet`.
It works much like the `LiftSession` API, taking either a type parameter or a string
that is a comet class's name. Both of the overloads also have a
`receiveUpdatesOnPage` parameter that is defaulted to `false`. When set to `true`,
it will automatically append the created `CometActor` to the page or AJAX request
so that it will receive updates.
- `S` also has a method for adding a comet to the currently rendering page or page
that invoked the current AJAX callback, `S.addComet`. It takes a `LiftCometActor`,
which you can get from `S.findOrCreateComet` if you don't have a direct handle
to it already.
- The internal client-side JavaScript API now supports aborting the current comet
request, mostly in order to support restarting the current comet cycle. This is used
when a new comet is received from the server to ensure the comet starts receiving
updates immediately.
- The comet snippet has been updated and simplified to work with these changes.
It also now has a `containerForCometActor` method that is publicly available and
lets you get the HTML container for any given comet actor. This lets you do your
own work to create a comet container without directly invoking the comet snippet.