meteor/meteor — pull request #680 by awwx (2013-02-13 14:39:08+00:00)
Title: Html attributes hook and browser identification

This commit is theoretically independent of the route policy PR,
in functionality, but had multiple merge conflicts with it. This PR branch thus
is based on the route policy PR. (That is, you should only merge this PR if you've
already merged the route policy PR, otherwise you'll get the route policy
commit as well).

Adds an html attribute hook, used by the appcache package to insert the
manifest attribute into the app HTML.

However, to use the hook the appcache package needs to be able to
identify the browser (to decide whether to include the attribute or
not for that browser).

We now have multiple places that want to identify the browser: the
unsupported browser page, the appcache package, and, if we eventually
implement not delivering large polyfills to browsers that don't need
them, in app HTML generation code as well.

To avoid detecting the browser in multiple places ad-hoc, this commit
creates a Meteor "browser" object, intended to be a standard way of
identifying the browser server-side. It uses but does not expose the
npm useragent module (we could choose a different mechanism to
identify the browser in the future if we wanted to). The browser
object contains

* `name`: the name of the browser in camel case
* `major`, `minor`, `patch`: integers describing the browser version

In addition to the html attribute hook, the appcache package also
needs a way to get from the connect `req` object to the identified
browser (browsers *start* caching when they see the manifest
attribute, but only *stop* caching when they get a 404 for the
manifest...)

Eventually though we'd like smart packages to be able to serve content
without having to plug directly into connect.

This commit thus also introduces an early version of a Meteor
`request` object, intended to be a high-level description of the
request without exposing details of connect's low-level `req`.
Currently it contains:

* `browser`: browser identification object described above
* `url`: parsed url, including parsed query params

To get started, as a temporary measure I've added a
`categorizeRequest` function to `__meteor_bootstrap__` which converts a
connect `req` to a Meteor `request`. (Suggestions for a better name
are welcome). This can go away once smart packages such as appcache
are being passed a `request` object directly when they serve content.

This allows `request` to be used uniformly: it is passed to the html
attributes hook, and the appcache package can also use it when deciding
whether to generate a 404 for the manifest.