Viewer mixins

_Note: This is a pull into the `viewer` branch._

We can do final cleanup in the `viewer` branch, but open a separate pull so we can make sure we all agree on the approach.

@shunter Take a look at this and merge if you're happy.
@emackey Your comments are also welcome (obviously so are everyone else's).