commit 5cb3e997aa502b5a6b241c18bffb41f355ad914d Author: John Bintz Date: Thu Aug 23 08:43:06 2012 -0400 initial commit, yeehaw diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d87d4be --- /dev/null +++ b/.gitignore @@ -0,0 +1,17 @@ +*.gem +*.rbc +.bundle +.config +.yardoc +Gemfile.lock +InstalledFiles +_yardoc +coverage +doc/ +lib/bundler/man +pkg +rdoc +spec/reports +test/tmp +test/version_tmp +tmp diff --git a/Gemfile b/Gemfile new file mode 100644 index 0000000..bfb18fd --- /dev/null +++ b/Gemfile @@ -0,0 +1,4 @@ +source 'https://rubygems.org' + +# Specify your gem's dependencies in bullseye.gemspec +gemspec diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..87b491e --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +Copyright (c) 2012 John Bintz + +MIT License + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..b8ff2f2 --- /dev/null +++ b/README.md @@ -0,0 +1,54 @@ +# Bullseye! + +An *extremely fast* shoot-from-the-hip implementation of [so-called Garber-Irish DOM-ready execution](http://viget.com/inspire/extending-paul-irishs-comprehensive-dom-ready-execution) +for the Rails asset pipeline. Could work with other Sprockets stuff down the road, too. But for now, it's +pretty married to Rails. Also, needs tests for the exactly four things that it does. Anyone wanna add exactly four Cucumber features? + +## Why? + +I got sick of on-page JavaScript. Also I like using the Asset Pipeline for what it's actually intended for, +reducing the number of HTTP requests. + +## How? + +Add the gem: + +``` ruby +gem 'bullseye' +``` + +Replace your `body` tag in your layout with: + +``` haml +!!! +%html + = bullseye_body do + = yield +``` + +That adds `data-action` and `data-controller` attributes to your `body` tag automagically. The controller +comes from `ActionController::Base.controller_path`, so it's the full namespaced underscored path (`Admin::UsersController` +becomes `admin/users`). + +Then, in `application.js`: + +``` javascript +//= require bullseye +``` + +Finally, create some controller/actions-specific files within `app/assets/javascripts/bullseye` +and give them the extenstion `.bullseye`. For instance, target `SitesController#show` in JS and CoffeeScript: + +``` javascript +// app/assets/javascripts/bullseye/sites/show.bullseye + +alert("I am showing a site"); +``` + +``` coffeescript +# app/assets/javascripts/bullseye/sites/show.bullseye.coffee + +alert "I am also showing a site" +``` + +Piece of cake. diff --git a/Rakefile b/Rakefile new file mode 100644 index 0000000..f57ae68 --- /dev/null +++ b/Rakefile @@ -0,0 +1,2 @@ +#!/usr/bin/env rake +require "bundler/gem_tasks" diff --git a/app/assets/javascripts/bullseye.js b/app/assets/javascripts/bullseye.js new file mode 100644 index 0000000..1d2ce3a --- /dev/null +++ b/app/assets/javascripts/bullseye.js @@ -0,0 +1,24 @@ +#= require jquery + +this.Bullseye = { + target: function(controller, action, callback) { + this.targets = (this.targets || {}); + this.targets[controller] = (this.targets[controller] || {}); + this.targets[controller][action] = callback; + }, + + exec: function(controller, action) { + if (this.targets[controller] && this.targets[controller][action]) { + this.targets[controller][action].apply(this.context); + } + } +}; + +Bullseye.context = this; + +$(function() { + var controller = $('body').data('controller'); + var action = $('body').data('action'); + + Bullseye.exec(controller, action); +}); diff --git a/bullseye.gemspec b/bullseye.gemspec new file mode 100644 index 0000000..44f3677 --- /dev/null +++ b/bullseye.gemspec @@ -0,0 +1,20 @@ +# -*- encoding: utf-8 -*- +require File.expand_path('../lib/bullseye/version', __FILE__) + +Gem::Specification.new do |gem| + gem.authors = ["John Bintz"] + gem.email = ["john@coswellproductions.com"] + gem.description = %q{TODO: Write a gem description} + gem.summary = %q{TODO: Write a gem summary} + gem.homepage = "" + + gem.files = `git ls-files`.split($\) + gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) } + gem.test_files = gem.files.grep(%r{^(test|spec|features)/}) + gem.name = "bullseye" + gem.require_paths = ["lib"] + gem.version = Bullseye::VERSION + + gem.add_dependency 'tilt' + gem.add_dependency 'sprockets' +end diff --git a/lib/bullseye.rb b/lib/bullseye.rb new file mode 100644 index 0000000..2c4bb69 --- /dev/null +++ b/lib/bullseye.rb @@ -0,0 +1,3 @@ +require "bullseye/version" +require 'bullseye/engine' if defined?(Rails::Engine) +require 'bullseye/tilt/bullseye_template' diff --git a/lib/bullseye/engine.rb b/lib/bullseye/engine.rb new file mode 100644 index 0000000..654f063 --- /dev/null +++ b/lib/bullseye/engine.rb @@ -0,0 +1,14 @@ +require 'bullseye/helpers/bullseye_helper' + +module Bullseye + class Engine < ::Rails::Engine + initializer 'bullseye.view_helpers' do + ActionView::Base.send(:include, Bullseye::Helpers::BullseyeHelper) + end + + initializer 'bullseye.sprockets', :after => 'sprockets.environment' do |app| + app.assets.register_engine '.bullseye', Bullseye::Tilt::BullseyeTemplate + end + end +end + diff --git a/lib/bullseye/helpers/bullseye_helper.rb b/lib/bullseye/helpers/bullseye_helper.rb new file mode 100644 index 0000000..d51fa80 --- /dev/null +++ b/lib/bullseye/helpers/bullseye_helper.rb @@ -0,0 +1,10 @@ +module Bullseye + module Helpers + module BullseyeHelper + def bullseye_body(options = {}, &block) + content_tag(:body, capture(&block), { 'data-action' => action_name, 'data-controller' => controller_path }.merge(options)).html_safe + end + end + end +end + diff --git a/lib/bullseye/tilt/bullseye_template.rb b/lib/bullseye/tilt/bullseye_template.rb new file mode 100644 index 0000000..64d958d --- /dev/null +++ b/lib/bullseye/tilt/bullseye_template.rb @@ -0,0 +1,28 @@ +require 'tilt' +require 'sprockets' + +module Bullseye + module Tilt + class BullseyeTemplate < ::Tilt::Template + def self.default_mime_type + 'application/javascript' + end + + def prepare + end + + def evaluate(scope, locals, &block) + parts = scope.logical_path.split('/') + action = parts.pop + controller = parts[1..-1].join('/') + + <<-JS +Bullseye.target('#{controller}', '#{action}', function() { + #{data} +}); + JS + end + end + end +end + diff --git a/lib/bullseye/version.rb b/lib/bullseye/version.rb new file mode 100644 index 0000000..87a21db --- /dev/null +++ b/lib/bullseye/version.rb @@ -0,0 +1,3 @@ +module Bullseye + VERSION = "0.0.1" +end