Skip to content

Instantly share code, notes, and snippets.

@mashiro
Created January 11, 2012 06:21
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save mashiro/1593345 to your computer and use it in GitHub Desktop.
Save mashiro/1593345 to your computer and use it in GitHub Desktop.
$ = jQuery
class Bucket
constructor: (@name = "__root__", @children = {}, @actions = {}) ->
getCallbacks: (actions...) ->
callbacks = []
Array::push.apply(callbacks, @actions[action] || []) for action in actions
return callbacks
setCallback: (action, callback) ->
callbacks = @actions[action] ||= []
callbacks.push callback
class AssetsDispatcher
constructor: (@root = new Bucket) ->
on: (options, callback) ->
data = @_parse options.controller, options.action
bucket = @root
bucket = (bucket.children[controller] ||= new Bucket(controller)) for controller in data.controllers
bucket.setCallback data.action, callback
return bucket
dispatch: (selector = "body", options = {}) ->
elem = $(selector)
controller = if options.controller? then options.controller(elem) else elem.data("controller")
action = if options.action? then options.action(elem) else elem.data("action")
data = @_parse controller, action
callbacks = []
@_dispatch @root.children, data.controllers, data.action, callbacks
callback(controller, action) for callback in callbacks
return callbacks.length > 0
_dispatch: (buckets, controllers, action, callbacks) ->
controller = controllers.shift()
@_dispatch buckets, [""], action, callbacks if controller != ""
bucket = buckets[controller]
if bucket?
Array::push.apply(callbacks, bucket.getCallbacks("", action))
#console.log "check: C[#{controller}] A[#{action}]"
#console.log callbacks
@_dispatch bucket.children, controllers, action, callbacks if controller != ""
_parse: (controller, action) ->
data = {}
data.controllers = $.trim(controller).split(" ") unless controller instanceof Array
data.action = $.trim(action)
data
$.assets = new AssetsDispatcher
@mashiro
Copy link
Author

mashiro commented Jan 11, 2012

How to use

First

app/assets/javascripts/application.js.coffee

#= require jquery
#= require jquery_ujs
#= require jquery-assets-dispatcher

Second

app/assets/javascripts/**

$.assets.on {controller: "users", action: "index"}, -> console.log "called on users:index"
$.assets.on {controller: "users photos", action: "show"}, -> console.log "called on users/photos:index"
$.assets.on {controller: "users"}, -> console.log "called on users:*"
$.assets.on {action: "new"}, -> console.log "called on *:new"

Finally

app/views/layouts/application.html.haml

#site{:data => {:controller => params[:controller].split('/').join(' '), :action => params[:action]}}
  :javascript
    $.assets.dispatch("#site");

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment