Live Reloading Chrome Apps and Extensions with Gulp and WebSockets

My new favorite tool these days is Gulp. It’s blazing-fast pipe-streaming architecture combined with its extensibility and ease of configuration make it, dare I say, simply delightful to use.

I’ve been tinkering on a Google Chrome Extension lately and I quickly discovered the annoying obstacle of constantly needing to reload the thing. With a background page or script running, you constantly have to flip between browser tabs and/or windows to do manual refreshes every time you want to see your changes. Icky stuff.

I had used gulp-livereload in the past to solve this issue for traditional front-end web app development, but it didn’t work for refreshing the background script. Then I realized I could pretty easily roll my own lightweight solution using WebSockets.

WebSockets is an implementation of the fabled ‘push notification’ technology of keeping a long-standing open connection between server and client for immediate synchronization. It benefits by having a web standardization that is used in all major browsers, and therefore has an exposed JavaScript API.

For the Node.js and Gulp end of things, I used the module ws:

1
npm install ws --save-dev

Then I added it to my Gulpfile and created a reload task for it, which I added to the relevant watch tasks:

Gulpfile.coffee
1
2
3
4
5
6
7
8
9
10
11
WebSocketServer = require('ws').Server
wss = new WebSocketServer(port: 9191)

gulp.task 'reload', ->
  client.send('reload') for client in wss.clients

gulp.task 'coffee', ->
  ...

gulp.task 'watch', ->
  gulp.watch ["*.coffee"], ["coffee", "reload"]

For the Chrome Extension, I created this little CoffeeScript and included it in both the content and background scripts:

reload-client.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
socket = null

@reloadClient = 
  connect: ->
    socket = new WebSocket('wss://localhost:9191')
    socket.onopen = -> console.log('connected')
    socket.onclose = -> console.log('closed')
    socket.onmessage = (message) ->
      if message.data is "reload"
        window.chrome.runtime.reload()

  disconnect: ->
    socket.close()

# uncomment to connect on load
# reloadClient.connect() 

That’s it! When gulp -w boots, a WebSocket server is instantiated. Whenever a coffee file saves, the server sends a ‘reload’ message to all of its clients. In the browser, calling reloadClient.connect() creates a WebSocket which will sit and wait fervently for its very important message, until you save your next source file.

Leave a Comment

Director.js: Dynamic Template Decorating From Declarative Attributes

Lately I’ve been doing lots of liberal caching in Rails with cache_digests for the super fast rendering it grants you. The more logic-less the templates are, the faster they render initially and the harder and more globally they can be cached.

For example, if there are no conditional checks involving current_user in a template, it can be cached to an entire account or site-wide rather than on a per user basis.

This caching pattern often leaves the need to spruce up templates with JavaScript after the page is rendered though. Consider the following template:

1
2
3
4
5
6
7
8
9
<% cache current_account do %>
  <label>Assigned to:</label>
  <select name="user_id">
    <option value="1">John Doe</option>
    <option value="2">Jane Doe</option>
    ...
  </select>
  </div>
<% end %>

Say you wanted to initialize the select by selecting the option of the currently signed in user. Normally I would add a small JavaScript function to fire on $(document).ready or on the page:change event. But flipping between JavaScript and templates on an individual basis felt tedious and inelegant, so I came up with the following tiny plugin:

director.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
direct = (opts) ->
  return unless $.isPlainObject opts
  _.reduce _.pairs(opts), (memo, opt) ->
    fn = director.directives[opt[0]] or $.fn[opt[0]]
    return memo unless _.isFunction fn
    fn.call(memo, opt[1])
  , $(@)

@director =
  direct: (el = "html") ->
    $(el).find("[data-direct]").each ->
      direct.call @, $(@).data('direct')
  directives: {}

What is going on here? Firstly, it assumes you are using jQuery (or Zepto with the data module) bound to $ and Underscore or Lo-Dash bound to _. Why re-invent the wheel, right?

If you call director.direct() without a variable, it will start at the top of the DOM but you can also call director.direct('#foo') to scope it to an element with the ID of ‘foo’. Director will then look within the scope for instances of data-direct and employ the handy ability of jQuery’s .data() method to turn an attribute value from JSON into an object.

_.reduce iterates through the pairs of the attribute-turned-object and calls they key as a function on $(@), passing in the value as the parameter. The key could then be any jQuery function. The memoized result is returned to the next key/pair so you can chain the statement together.

Given the original example above, you can then add something like this higher up the DOM:

1
<div id="assign" data-direct='{"find":"select","val":"<%= current_user.id %>"}'>

When director.direct() is called, without writing one-line of JavaScript this would automagically get turned into:

1
$("#assign").find("select").val("2")

I also created an empty plain object of director.directives for adding any special functionality that simple jQuery commands can’t provide. Just make sure to return this so you can chain your statements together.

For more examples and further development, star director on Github.

Leave a Comment

Turboboost: Enhanced AJAX handling for Rails apps

Update 2/23/14

This gem was renamed from turboforms to turboboost for a couple reasons:

  • A simpler, unmaintained gem named turboforms already exists.
  • The gem now provides enhanced AJAX handling to links and other non-form elements.

I’ve added some scoped response rendering options so you can do convenient JavaScript rendering in your controller actions like:

1
2
3
respond_to do |format|
  format.js { render partial: 'task', object: @task, prepend: "#todo-list" }
end

Check out turboboost on Github for more.


Lately I’ve been working on a Rails app that has been leveraging Turbolinks to really speed up the app experience. As I’ve talked about before, you do have to follow some JavaScript conventions for your app to be Turbolink-friendly, but such is the case for any performance-oriented JavaScript workflow. The sweet thing about Turbolinks is you get to hold close your dear bag of Rails tricks.

In our app though, there are lots of forms that send POST and PUT requests. Every time a form gets submitted, the browser would wait for a response and then follow the success redirection or render the invalid response with a full-page reload. Either way, the screen would flash and the scripts and styles would need to get reloaded in a very non-turbo way.

Sure, the jQuery unobtrusive scripting adapter provided by jquery-rails gives us access to binding to AJAX responses, but simply dumping a success or error response into the body doesn’t play nice with Turbolinks ability to preserve the browser’s state and history at these checkpoints of user activity. In search for a seemless solution, turboboost was born.

Design & Behavior

In order to bring AJAX control over our app’s forms in a Turbolinks compatible way, I defined some assumptions:

  • For GET requests, Turbolinks should visit the form’s action URL with the serialized data appended to it as a query string. This preserves navigable history states for things like live-updating search filter forms.

  • For other request types (POST, PUT, PATCH, DELETE, etc), an AJAX request should hit the Rails controllers. Then:

    • If the response has a redirect_to declaration, do not reload. Instead, visit that route with Turbolinks.
    • If there is an error, don’t visit anything with Turbolinks. Instead, the errors will be sent through the global document event turboboost:error. Optionally, the errors can be prepended to the form as HTML.
  • Turboboost only works on forms that you define with turboboost: true in your Rails form helper options (ex: form_for @post, turboboost: true do |f| ...) or manually with a data-turboboost attribute.

  • When a Turboform has an AJAX request in process, do sensible things like disable that form’s submit button.

These resulted in substantially faster loading upon successful form submissions with redirects, as only the body is swapped out. As a bonus, since failed form submissions are caught and immediately sent back to the app in JavaScript, you can cache your form views harder, since you don’t have to re-render the form view in an invalid state.

Example Usage

In its simplest server-side implementation, a controller action would look like this:

1
2
3
4
def create
  post = Post.create!(params[:post]) <- trigger exception if model is invalid
  redirect_to post, notice: 'Post was successfully created.'
end

If the post is invalid, a rescue_from handler will pass off the errors to JavaScript through the turboboost:error event. If the post is successfully created, the app will visit the post_url with Turbolinks if it was sent from a Turboform. Otherwise, the redirect will happen like normal.

You can also render the JSON error messages explicitly with the method render_turboboost_error_for(record), ex:

1
2
3
4
5
6
7
8
9
10
11
def create
  @post = Post.new(post_params)
  if @post.save
    redirect_to @post, notice: 'Post was successfully created.'
  else
    respond_to do |format|
      format.html { render 'new' }
      format.js { render_turboboost_error_for(@post) }
    end
  end
end

JavaScript options and events

By default, Turboboost will render returned errors with the same HTML structure used in the default Rails generators and prepend it to the form. The structure looks like this:

1
2
3
4
5
6
7
<div id="error_explanation">
  <ul>
    - for error in errors
      <li>= error</li>
    - end
  </ul>
</div>

Or this can be disabled and you can roll your own error handler:

1
2
3
4
Turboboost.insertErrors = false

$(document).on "turboboost:error", (e, errors) ->
  console.log(errors) # <- JSON array of errors messages

There is also a turboboost:success event that is trigger and passed a hash of the flash messages if they are present. You may also prevent redirecting on any Turboform by adding the attribute data-no-turboboost-redirect to your form element if you just want to handle the response and returned flash messages manually:

1
2
$(document).on "turboboost:success", (e, flash) ->
  console.log(flash) # -> {'notice': 'Post was successfully created.'}

More on Github

Turboboost is still in its infancy, but I think it has some legs. For install instructions and more info, follow development on Github. And as always, pull requests and comments are welcome.

Leave a Comment

Pimp Your Rails Gemfile Development Group

The Rails development-oriented RubyGems scene is out of control right now. The number of high-quality open-source tools you can stuff into your Gemfile and bundle up these days is almost scary. When I start a fresh Rails project, I’m currently injecting a development group that looks something like this:

Gemfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
group :development do
  gem "pry-rails"
  gem "pry-plus"
  gem "awesome_print"
  gem "rack-livereload"
  gem "guard-livereload"
  gem "guard-pow"
  gem "powder"
  gem "terminal-notifier-guard"
  gem "guard-shell"
  gem "quiet_assets"
  gem "spring"
  gem "xray-rails"
  gem "better_errors"
  gem "binding_of_caller"
  gem "sextant"
  gem "letter_opener"
  gem "bullet"
end

Some of these gems help keep me out of the guts of my code, while some of them thrust me right into the thick of my code’s guts, right where I need to be for a better look. Others make my time and effort more efficient by removing distraction, printing things more cleanly, keeping me from repeating commands, or delivering updates straight to the browser. Here’s a brief run-through:

pry-rails sets the Rails console from plain ol’ irb to the superior pry. pry-plus adds some extra goodies. The list of enhancements that pry brings is pretty extensive but some of my favorites are:

  • You can use ls to list all methods on any Ruby object, analogous to shell command of the same name for listing a folder’s contents.
  • ? <method-name> will print the documentation on the named method.
  • The variable _ will always refer to the output of the last command.
  • wtf? will reveal the file and line number of the last error.

If you want to learn more about pry, Conrad Irwin’s Rails Conf talk is very worth a gander.

awesome_print does exactly its name. It will print your irb or pry command output awesomely with color and alignment. I also enable it globally by adding the following to my ~/.pryrc file:

.pryrc
1
2
require "awesome_print"
AwesomePrint.pry!

guard-livereload and rack-livereload will bring any modifications to view-related files right up into the browser for you. Script and template file updates will cause a full page refresh, but updated stylesheets will magically and almost instantly take effect on the screen.

I use pow to manage my multiple development server environments and guard-pow will auto restart a booted server intelligently when pre-loaded files are updated. powder makes running pow commands dead simple.

terminal-notifier-guard brings your guarded action’s messages up through OSX 10.8 User Notifications

guard-shell is for running shell scripts on file changes. My favorite use so far is for auto-optimizing images in the assets folder with ImageOptim:

Guardfile
1
2
3
4
5
6
guard 'shell' do
  watch %r{^app/assets/images/.} do |file|
    n file[0], "#{file[0]} changed"
    `open #{file[0]} -a ImageOptim`
  end
end

quiet_assets turns off all the noisy and usually irrelevant asset pipeline log details from development.log.

spring is a Rails application preloader, which is a substantial time-saver when hoping in and out of rails console or running rspec. To use it, just prefix your desired command with spring. The first time you run a spring command in a shell, it will keep an instance of the app running in a background process so your next spring command will not have to reboot it. Ryan Bates compares spring with alternate preloaders zeus and commands in a recent RailsCast, but I’m finding spring to best fit my workflow.

xray-rails is some seriously spooky voodoo. You can think of it as the “Inspect Element” for your Rails view files. Toggling it on and off with a hot-key in the browser, it reveals the quadrants that represent all the various Ruby and Script templates on the screen. Clicking on one will open the relevant file in Sublime Text or whatever editor you set in ~/.xrayconfig (cough Emacs cough).

better_errors gives you a much more informative and navigable browser experience than the default Rails error page when things blow up. It is best combined with binder_of_caller which opens a full-blown interactive Ruby REPL at the point in your app’s code where things when wrong right there in the browser (!).

sextant is a tiny Rails engine that will output your application’s routes at the path /rails/routes, because no one has time to continually run rake routes. Luckily this is no longer needed in Rails 4.0+ as the core functionality has been merged into master.

letter_opener lets you preview an app sent email in a new browser tab instead of actually sending it. This is typically much more convenient for testing than wiring up SMTP settings and digging into your email client.

bullet is handy for sniffing out pesky performance-draining N+1 queries. You can configure it to print to your Rails development log, a dedicated bullet.log, your browser’s console, even send growl notifications or XMPP messages.

Having this ever-expanding tool-belt continually makes my Rails coding faster and more convenient. If you have any other development gem secret weapons, please leave a comment.

Leave a Comment

Quick Emacs Buffer Switching with ace-jump-mode

Update 6/18/13

I recently put in the effort to turn this into a more convenient Emacs lisp package. Enhancements include:

  • No longer are your pre-existing ace-jump-mode and bs settings clobbered. perspective mode is optional.
  • When the ace-jump-buffer menu is activated, C-g or any non-found ace-jump key-binding will clear ace-jump-mode and dismiss buffer menu.

This article’s code should only be entertained as a reference to the initial thought experiment. Grab the latest version on Github:

https://github.com/waymondo/ace-jump-buffer

Or install directly from MELPA:

1
package-install ace-jump-buffer

Beyond typing and text-editing related commands, switching buffers is my most common Emacs action. I’m constantly hopping back and forth between scripts and stylesheets and templates, popping into shells, etc. ido-mode’s fuzzy-match choosing is typically the de facto standard of this kind of interface: after triggering an appropriate binding you are usually several keystrokes from naming and selecting your target. But life is short, can we do this faster?

There are also buffer flipping managers like iflip that behave much like beloved ⌘+TAB application switching, but when buffers start to pile up it can take a handful of repeated commands to get where you are going.

ace-jump-mode got me thinking. I’m continually finding it to be super useful in my day to day workflow. In just 2 or 3 keystrokes you can put your cursor anywhere in your Emacs environment. Then I realized I could bend it to allow me to hop to any buffer in 1 character. Here it is what I came up with:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
(require 'bs)
(require 'ace-jump-mode)
(require 'perspective)

;; simple layout, increase window height
(setq bs-max-window-height 30
      bs-attributes-list (quote (("" 2 2 left " ")
                                 ("" 1 1 left bs--get-marked-string)
                                 ("" 1 1 left " ")
                                 ("Buffer" bs--get-name-length 10 left bs--get-name))))

;; filter buffers to current perspective
(add-to-list 'bs-configurations
             '("persp" nil nil nil
               (lambda (buf)
                 (with-current-buffer buf
                   (not (member buf (persp-buffers persp-curr)))))) nil)

;; on end of ace jump, select buffer
(defun bs-ace-jump-end-hook ()
  (if (string-match (buffer-name) "*buffer-selection*")
      (bs-select)))

(add-hook 'ace-jump-mode-end-hook 'bs-ace-jump-end-hook)

(defun ace-jump-buffer ()
  (interactive)
  (bs--show-with-configuration "persp")
  (setq ace-jump-mode-scope 'window)
  (beginning-of-buffer)
  (call-interactively 'ace-jump-line-mode))

So what’s going on here? bs is a lightweight, built-in emacs lisp package for buffer switching, seemingly a predecessor to buffer-menu and ibuffer. I choose it for its simplicity and configuration. As I rely heavily on perspective for keeping my workspaces (projects) organized, I created a configuration to only display buffers in the current one.

Upon triggering ace-jump-buffer, the bs buffer switching popup appears and ace-jump-line is called, placing a character at the beginning of each line. The buffer ordering is from most recently viewed to backwards in time, so you can assume the current buffer is c, the previous buffer is d, and so on. Pressing the key that matches the line’s character selects the buffer.

After about a week I’m finding it to be quite effective. Perhaps I’ll wrap it up and submit it to MELPA if anyone else does to. You can browse my entire Emacs setup here.

Leave a Comment

Elegant Function Timer Method Decorator in CoffeeScript

CoffeeScript is so badass. Given its transpiling and symbiotic nature, we can borrow our favorite conventions from our favorite languages and let the ugly, optimized JavaScript runtime version get compiled behind the scenes.

This is great news for people like myself who entered the programming game via Ruby (and/or were spoiled by it) and now struggle to efficiently read and write code if it is not simple and concise and has that human-readable touch. In today’s landscape of endless mountains of JavaScript, any help to mask its shortcomings and break out of “callback hell” is a welcomed improvement to my workflow and code structure.

Method Decorators

In this vain, I have struggled with the lack of a good pattern for decorating methods – doing things before, after, or around functions. For the Rubyist on Rails, you can think of the handiness of ActionController’s filter methods and ActiveRecord’s callbacks. But alas, JavaScript makes it syntactically tricky with its function scoping and closures to properly pass arguments and callback functions around in a peaceful manner.

Then I discovered Reginald Braithwaite’s awesome method decorators and combinators:

method-decorators.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
this.before =
  (decoration) ->
    (base) ->
      ->
        decoration.apply(this, arguments)
        base.apply(this, arguments)

this.after =
  (decoration) ->
    (base) ->
      ->
        decoration.call(this, __value__ = base.apply(this, arguments))
        __value__

this.around =
  (decoration) ->
    (base) ->
      (argv...) ->
        __value__ = undefined
        callback = =>
          __value__ = base.apply(this, argv)
        decoration.apply(this, [callback].concat(argv))
        __value__

Definitely read Reginald’s post for more of an overview on these. But for now, onto the practical example.

The Timer

I’ve been mainly working on native-wrapped HTML5 mobile apps lately and I wanted a way to easily profile any function and log the milliseconds it takes to execute. It turns out I was able to do this as a small extension to this.around.

1
2
3
4
5
6
@timer = (name) ->
  around (fn) ->
    t = new Date().getTime()
    fn()
    ms = new Date().getTime() - t
    console.log("#{name} - #{ms.toString()}ms")

Give the timer a name and it applies an around filter to your returned function, which checks the difference between the milliseconds before and after the function call and prints it to the log. Your expected value of this and any named arguments will be maintained in your decorated method. For example, say you wanted to profile how long it takes a Backbone View to render.

dashboard.coffee
1
2
3
4
5
6
7
class Dashboard extends Backbone.View
  # ...
  render: timer("dashboard render") (collection) ->
    @$el.html @template items: (collection or @collection).toJSON()
    @

# example console log: dashboard render - 24ms

Easy peasy. This doesn’t account for deferred events like ajax callbacks, but it does let me analyze the client-side operations that I’m most interested in optimizing.

Leave a Comment

Custom Global Emacs Bindings with Key Chord and the Semi-Colon Key

Incessant tweaking of my Emacs setup is easily my nerdiest hobby these days. Sure, there are plenty of modern text editors that come out of the box basically fully-featured, but what’s the fun in that? Despite the learning curve, I think learning Emacs and molding it with lisp is a great creative exercise that can yield some powerful efficiencies.

One of my newly favorite lisp packages is key-chord-mode. With it, you can bind commands to combinations of key-strokes. For example, I’ve set the chord of the two angle bracket keys <> to execute sgml-close-tag, which creates a closing tag for whatever unclosed HTML/XML tag you are inside. Similarly, I’ve set the curly brackets keys {} to execute open-brackets-newline-and-indent which is a custom defun for opening a CSS definition, JavaScript function, or Ruby block and setting the cursor inside it.

My favorite way to abuse key-chord though is to treat the semi-colon as my own prefix for custom global bindings. Here is what my semi-colon chords currently look like:

1
2
3
4
5
6
7
8
9
10
11
12
(key-chord-define-global ";b" 'ido-switch-buffer)
(key-chord-define-global ";r" 'recentf-ido-find-file)
(key-chord-define-global ";f" 'ido-find-file)
(key-chord-define-global ";g" 'magit-status)
(key-chord-define-global ";m" 'ace-jump-mode)
(key-chord-define-global ";c" 'hemacs-todo-capture)
(key-chord-define-global ";t" 'hemacs-goto-todos)
(key-chord-define-global ";o" 'magit-in-perspective)
(key-chord-define-global ";s" 'persp-switch)
(key-chord-define-global ";l" 'persp-shell)
(key-chord-define-global ";d" 'dired-jump-other-window)
(key-chord-define-global ";a" 'ack-and-a-half)

Since this is basically an empty binding namespace, you can use the most memorable mnemonic letters (“o”pen project, switch “b”uffer, etc). You don’t have muck around with overriding or conflicting with command prefixes between lisp packages or memorizing multi-command. You also don’t have to rely on bindings involving the super key (⌘ in OSX), which may conflict with system-level bindings. That means they will work inside Apple Terminal or iTerm as well as Carbon Emacs.

The biggest consideration to make when defining chords in general is to stray from key combinations you might accidentally fire when typing away. The semi-colon approach works for me because I’m not writing much JavaScript in these wonderful CoffeeScript days, and when I do I’m not typically ending my lines in semi-colons, since extraneous whitespace on lines is deleted in my before-save-hook. My CSS bindings spit out the semi-colon for me as well, so I haven’t had any conflicts so far. The runner-up character candidate I was thinking of using for this chord namespace was the ` key, but it’s way up in the top-left of the keyboard and the semi-colon is ergonomically placed straight up downtown in the home row keys.

You can browse my entire Emacs setup here.

Leave a Comment

Trippy 3D hover animations with CSS3 perspective

I recently updated my minimal personal site with some links to my online existence and decided to try and spice up the design with a full-screen 3D animation. I started by randomly selecting some of my favorite looking unicode characters – € ç ∅ ξ φ ð ⊗ ∴ ∉ ♣ ¤ ‰ ◊ and stuffing them into layers of nested <span> structures.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<div id="beejeez">
  <div id="bg1">
    <span>
      &phi;
      <span>
        &phi;
        <span>
          &phi;
          ...etc
        </span>
      </span>
    </span>
  </div>
</div>

Then with Less CSS I blew up the characters huge, put them on z-index: 0, declared some CSS3 transitions and 3D-related properties, and made it so each nested <span> is slightly more transparent. 3d translated, and rotated from the previous layer.

beejeez.less
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#beejeez {
  position: fixed;
  font-size: 35em;
  z-index: 0;
  top: -.5em;
  left: 0;
  #bg1 {
    .transition(all .8s ease-in-out);
    .transform(translate3d(0,0,0));
    .transform-style(preserve-3d);
    .backface-visibility(visible);
    span {
      .transform-style(preserve-3d);
      position: absolute;
      top: 0;
      left: 0;
      .opacity(77);
      .perspective-origin(50% 50%);
      .transform(~"translate3d(-.004em, -0.002em, 0.01em) rotateX(2deg) rotateY(3deg)");
    }
  }
}

Finally, I wanted the background characters to react dynamically and randomly when hovering around the page. The way I did this is by animating the perspective property based on the mouse’s X and Y coordinates in the window. The visual effect is the same principle as changing the focal length of a camera lens – the higher the perspective number is, the flatter the background layers appear; the lower the perspective, the “wider the lens is” and more exaggerated each layer’s changed properties appears.

beejeez.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# prefix a css attribute declaration with vendor prefixes
vendorPrefix = (attr, v) ->
  o = {}
  o["-webkit-#{attr}"]=v
  o["-moz-#{attr}"]=v
  o["-ms-#{attr}"]=v
  o["#{attr}"]=v
  o

# set each bg layer's perspective based on an event positioned within the window
setPerspective = (e) ->
  x = e.pageX / window.innerWidth
  y = e.pageY / window.innerHeight
  $("#bg1").css(vendorPrefix("perspective",(x*500)))

# upon the mouse moving in the window, calculate the perspective values every 200ms
$(window).mousemove (e) -> _.debounce setPerspective(e), 200

The final result is pretty trippy. Although it is probably too hardware intensive to be practical and really only looks good in Webkit browsers like Chrome and Safari, it was an interesting experiment. I put together a JSFiddle of the general components if anyone wants to hack around with it.

Leave a Comment

Ember.js and Rails Authentication Gotchas

I’ve been working on an app that is Ember.js on the front-end and Ruby on Rails on the back. Communication between the two has been pretty painless with Ember Data’s RESTAdapter and Active Model Serializers, but I ran into some snags with user authentication. Here’s some things I learned.

CSRF tokens with Ember AJAX requests

In order to comply with with Rails’ built-in Cross-site request forgery protection, you need to send a generated CSRF token with any request. Rails is typically generous in supplying this via a hidden input when using form_for and form_tag and is added to all AJAX requests when using the jquery-rails gem. An Ember app most likely has no need for jquery-rails, so I ripped out the relevant request header piece. Just make sure <%= csrf_meta_tags %> is in your layout’s <head> and add the following to your bundled scripts:

1
2
3
4
$ ->
  token = $('meta[name="csrf-token"]').attr('content')
  $.ajaxPrefilter (options, originalOptions, xhr) ->
    xhr.setRequestHeader('X-CSRF-Token', token)

Sorcery remember_me cookie header

For my ruby authentication gem, I went with Sorcery over the popular Devise since I didn’t need a toolbox of features or its generated views. Creating signup and login methods in UsersController and SignupController respectively were easy enough, but I couldn’t get the remember_me option to be honored when submitting the form with AJAX. Upon digging through Sorcery’s source, the issue was a hard-coded option of httponly: true when setting the remember_me cookie. When this was set to false, the cookie was properly returned in the JavaScript response header. I created a pull-request for overriding this option in Socery’s initiliazer which was recently merged into master, so this shouldn’t be an issue moving forward.

Ember route before filter redirection hook

Now that Rails wasn’t barking about CSRF tokens and was retaining the current_user, I needed a way to prevent the Ember app from entering a route where a logged-out user didn’t belong. In an effort to keep it simple, I’m using a simple extension to Ember.Route:

ember-redirection.coffee
1
2
3
4
5
6
7
8
Ember.Route.reopen

  setup: ->
    beforeFilterRedirection = Em.get(@, 'beforeFilterRedirection')
    if beforeFilterRedirection? and (redirection = beforeFilterRedirection())?
      @router.transitionTo redirection
    else
      @connectOutlets.apply(@, arguments)

When the route is setup, it checks to see if the route has a function defined called beforeFilterRedirection and if it does, it evaluates it and if the function returns a value, it is assumed to be the route to redirect to and sends you over that way. Otherwise, it continues onward to connect the route’s outlets like normal. An example implementation would look like this:

router.coffee
1
2
3
4
5
6
7
...
  dashboard: Em.Route.extend
    route: "/dashboard"
    connectOutlets: (router) ->
      router.get('applicationController').connectOutlet('userDashboard', App.currentUser)
    beforeFilterRedirection: ->
      "welcome.index" unless App.currentUser
Leave a Comment

Simple Lazy Loading jQuery Plugin and Defense of Turbolinks

About a month ago, a big Rails app I’ve been working on made the big switch over to Turbolinks. Being a monstrously JavaScript-infused UI experience, naturally there was code refactoring to be done. There were basically 3 patterns I followed to make it turbo-ready:

#1 – Lightweight and common functions that were used site-wide were declared unobtrusively via event delegation on the document object.

1
$(document).on 'click', '.foo', -> $(@).bar()

#2 – Page/interface-specific initialization functions were bound to custom jQuery events.

publisher.coffee
1
2
3
4
$(document).on 'init:publisher', (e, s) ->
  $scope = if s? then $(s) else $("html")
  return unless $scope.find("#publisher")
  # initialize that publisher

Here, the s argument placeholder allows us to pass in the scope of the DOM we are only interested in initializing as a jQuery selector, i.e. $(document).trigger("init:publisher","#content"). If no argument is supplied, the scope defaults to the entire page. This allows us to trigger these events more conservatively which is particularly useful for custom non-turbolinks ajax callbacks. If the parent element that needs initializing isn’t found within the scope, the function doesn’t waste any more time.

#3 – The page:change event assumed the role of document:ready.

pagechange.coffee
1
2
3
4
5
6
7
# first page load
$ -> $(document).trigger "page:change"

# each turbolink page load
$(document).on "page:change", ->
  $(document).trigger "init:publisher"
  ...

Once scripts were massaged into place, the app was multitudes faster. Most page requests were completed under 300ms and the lack of a loading page flash gave the app a much more native-like experience. The dashboard, however, was still taking too long to load. The dashboard#index controller action was heavy – it had to publisher with tabbed forms for different content types, a stream of recent activity had to be rendered, and a handful of sidebar widgets had to each run their specific database queries.

Since the various sidebar widget queries were the slowest chunk of dashboard#index, as well as the least immediately relevant information on the page, they were the prime candidate to be lazily loaded. I extracted them to their own controller actions that render widget partials and created routes for each of them. Then I wrote this tiny jQuery function to load them after the new page was turbolinked in.

jquery.lazy.coffee
1
2
3
4
5
6
7
8
$.fn.lazy = ->
  @each ->
    $this = $ @
    url = $this.attr('data-lazy-url')
    $.get url, (resp) ->
      $this.replaceWith(resp)

$(document).on "page:change", -> $("[data-lazy-url]").lazy()

On the initial dashboard view, an <div> empty with an attribute of data-lazy-url=<%= specific_widget_url %> holds the place for the widget that is on the way. If you need to update the widget before the next page:change, you can the add data-lazy-url attribute to outermost element of the returned widget and call $("[data-lazy-url]").lazy() whenever you need to. The result was a huge speed boost, cutting the page load time in half, and the widgets were usually in place before the user would even notice them not being there.

There have been mixed feeling on turbolinks since DHH released it. I do think that the “true” future of web applications will follow the course of seeing a tighter relationship between JavaScript app frameworks and JSON API’s, where the UI is managed and built within the browser while only sending data back and forth to the server. But I can vouch for the turbolinks (or pjax) approach being a super boost to a Rails app’s performance and experience. What I don’t accept is the grumping that turbolinks most likely forces you to re-factor your JavaScript code, due to what it grants you for the effort required, especially when compared to the effort of migrating an app to something like Ember. With a nominal bit of effort and consideration, and ideally coupled with good caching and a healthy concurrent server, you can keep rocking with your slim templates, jQuery plugins, and the rest of your bag of Rails tricks without rubbing against the grain of familiar and well-worn conventions.

Leave a Comment