Fix diff toolbar gradient in Firefox

We had originally implemented this as a gradient that went from white to
"transparent". While this looked good in Chrome, in Firefox it looked
oddly grayish. I believe that Firefox was transitioning to transparent,
but since it didn't know what color of transparent, it transitioned to
mid-gray at full transparency, causing a strange gray color.

To fix this, I changed the color that we transition to in the gradient
from "transparent" to rgba(255, 255, 255, 0), which is fully-transparent
white.

Closes #100.

Change-Id: I4e40a0c8671dea207916d940ebf8b51b9115cb39
Allow elements to specify multiple keyboard shortcuts

We want to add `J` and `K` as aliases for `]` and `[`, respectively. To
do this, we first need to allow these elements to have multiple keyboard
shortcuts.

The `~=` in the attribute selector will match elements whose attribute
value is a list of space-separated values, one of which is exactly equal
to the value given in the selector. This will enable the functionality
we need for this feature.

Addresses #99.

Change-Id: Iaa7e5b9c6df755fcbef6c68b9f6088801fb77fee
Dynamically associate shortcut keycode with character

We had an object that mapped keycodes that we have been using as
shortcut keys to their character strings. However, we can do this
dynamically via `String.fromCharCode()`. Although there will be a
performance penalty for this, I don't think avoiding that penalty
warrants the extra complexity at this time.

In service of #99.

Change-Id: Ib1cae0ab3257da4406953df53c50af8acd0488de
Add 'J' as an alias for ']' and 'K' as an alias for '['

I think these keys will be more intuitive and require less hand movement
than the square brackets.

Closes #99.

Change-Id: I3242024da793c0345ee22073a5c63da955cb8cc4
Re-order J and K shortcuts in modal

This places these shortcuts in their natural order.

In service of #99.

Change-Id: I8bb90f31764c49978cb0b12858167785507322f4
Improve whitespace in keyboard shortcut JS

I simply shifted some whitespace around in this file in an attempt to
improve the readability of the code slightly.

Change-Id: I4e8ae25c73b687ee03df277ebf9fdc409fbf3663
Refactor animation prevention into own method

I intend to do some work to this file, and the levels of nesting made it
harder to understand what was going on.
Refactor snapshotting into own method

I intend to do some work in this file, and I wanted to clean it up a bit
first.
Wait until page is ready before taking snapshot

Before this commit, we used to wait five seconds before taking the
snapshot. We did this to make sure that asynchronously loaded
elements had time to render on the page. This solved most of the
problems, but we always wanted something more robust. This commit
attempts to replace the timeout-based solution with one that listens
events fired when resources are fetched, and trigger the snapshot as
soon as we're no longer waiting for anything.

PhantomJS has two methods that you can implement to solve things like
this: `onResourceRequested` and `onResourceReceived`. We implement these
and keep a list of active resources. As soon as a (potentially) last
resource is received, we start a short timer which will trigger the
snapshot to be taken. If another resource is needed within the timeframe
of that running timer, we cancel the snapshot-taking and start waiting
for the response for the (potentially) last resource once more.

If this strategy for some reason fails, there's a 20 second fallback
timer that will trigger the snapshot. And in case no resources are
requested from the page at all, there is a 1 second initial timer that
will trigger the snapshot.

All in all, a fairly complicated structure. My initial testing shows a
significant improvement though. Fast pages are snapshotted way faster
(down to 2.5 seconds) and I haven't noticed any issues with more
complicated pages.
Re-compare with same snapshot as before

When you hit the "Re-compare" button on the snapshot page, we used to
compare the snapshot against the current baseline and not the baseline
that was at the time of first comparison. This was confusing, and led to
situations where hitting that button would remove the old diff and
either replace it with a diff to some other snapshot, or with no new
diff at all, since we only compare snapshots with a baseline if the
baseline is older than the snapshot.

I've fixed this by caching the compared_with snapshot and reusing that
when re-comparing. I'm aware of the fact that the snapshot_diff model
already stores this information, but we wipe out that reference when
re-comparing, and I would have had to make larger structural changes in
order to use that information.
Prevent comparer to trigger when re-taking snapshot

This fixes a bug where the comparer worker was triggered immediately
when you hit the "Re-take snapshot" button. The worker would error out
quickly because the snapshot image was no longer available. The fix was
to add a check for the image being there before triggering the comparer.
This was more complicated than I first though, mostly due to how the
paperclip gem handles attachment deletions.

I though that `snapshot.image = nil` would result in `snapshot.image ==
nil`, but no, `snapshot.image` returns a non-nil value even after that.
However, you can check for the existence of `snapshot.image_file_name`
instead.
Fix broken snapshots controller spec

I introduced a bug in my last commit by changing the characteristics of
the snapshot under test. I did that to make sure that the buggy behavior
of triggering a comparer when retaking the snapshot was taken care of.
By using a combination of :with_baseline and :with_diff traits I fixed
the spec and at the same time kept the validation that the comparer
wasn't triggering.
Animate snapshot thumbnail while still processing

Before a snapshot has been taken, we render a clock icon and animate its
opacity up and down to signify that it is actively being worked on and
is not ready to be reviewed. We should keep animating these after the
snapshot has been taken, before the diff has been generated to clearly
communicate that these items are not ready for review yet.

Closes #101.

Change-Id: I5118b9a87d0d7ae03b56383b7298400fe87bfa78
Remove unused .snapshot-baseline style

We haven't used this style since f279eff0d1ac9362285.

Change-Id: I3b03a5d733d6b3b150267ff936759c138a5d3e91
Update compass 0.12.4 -> 0.12.5, sass 3.2.17 -> 3.2.19

Change-Id: I51df1e78cff8dde8cb33a8ec4523c6f19285285e
Update sprockets-rails 2.1.1 -> 2.1.3

Change-Id: I1b67e0d379fb666181b0cadb9901fcd3bd1a759b
Update cocaine 0.5.3 -> 0.5.4

Change-Id: I6210cee145a5efb1292d4c0eddc0e4be45a4d114
Add flamegraph gem to development group

I have been using this a lot in development for finding bottlenecks to
optimize. I think that it is useful enough to keep it around in the
Gemfile. At minimum, this will save me some time every time I want to
jump into optimization mode.

Change-Id: Ie0581a203d61fa17fd8f363e48e0181553b7ac05
Add debug logs to take-snapshot.js

I've been trying to debug why (in some cases), images aren't fully
loaded. @lencioni saw this while snapshotting his twitter profile,
https://twitter.com/lencioni, and I managed to reproduce. To better
understand what's going on, I've added some debug logging that you can
turn on when manually taking a snapshot.

By default, the logs don't show up. But if you pass in `debug: true` in
the json argument, they are logged to standard out. Here's an example:

phantomjs ./script/take-snapshot.js
"{\"address\":\"https://twitter.com/lencioni\",
\"viewportSize\":{\"width\":1000, \"height\":1000},
\"outfile\":\"/tmp/screenshot.png\", \"debug\": true}"

After doing this, I spent a lot of time trying to reproduce the problem
from the command line (with the above command). But I was never able to
do get the same issue to appear. I'm adding these debug logs
anyway, to allow others to try it out and see if they can find out
what's going on.
Change button text when starting sweeps

The button on the new sweep form used to say "Save". "Start sweep" is
better.