zaarly-sinatra-sprockets 0.0.2.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,10 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
4
+
5
+ gem 'sprockets', '~> 2.0'
6
+ gem 'uglifier'
7
+ gem 'closure-compiler'
8
+ gem 'yui-compressor', :require => "yui/compressor"
9
+ gem 'execjs'
10
+ gem 'therubyracer'
@@ -0,0 +1 @@
1
+ require 'sinatra/sprockets'
@@ -0,0 +1,51 @@
1
+ require 'sinatra/sprockets/configuration'
2
+ require 'sinatra/sprockets/asset_paths'
3
+ require 'sinatra/sprockets/helpers'
4
+ require 'sinatra/sprockets/static_compiler'
5
+
6
+ module Sinatra
7
+ module Sprockets
8
+ def self.configure(&block)
9
+ block.call(config)
10
+ raise ArgumentError, "Cannot initialize Sprockets Environment without an app reference" if config.app.nil?
11
+
12
+ @environment = ::Sprockets::Environment.new(config.app.root)
13
+
14
+ config.paths.each do |path|
15
+ environment.append_path(File.join(config.app.root, path))
16
+ end
17
+
18
+ if config.compress_assets?
19
+ environment.js_compressor = Closure::Compiler.new
20
+ environment.css_compressor = YUI::CssCompressor.new
21
+ else
22
+ environment.js_compressor = false
23
+ environment.css_compressor = false
24
+ end
25
+
26
+ if config.manifest_path
27
+ path = File.join(config.app.root, config.manifest_path, "manifest.yml")
28
+ else
29
+ path = File.join(config.app.settings.public_path, 'assets', "manifest.yml")
30
+ end
31
+
32
+ if File.exist?(path)
33
+ YAML.load_file(path).each do |path, value|
34
+ config.digests[path] = value
35
+ end
36
+ end
37
+
38
+ environment.context_class.instance_eval do
39
+ include Helpers
40
+ end
41
+ end
42
+
43
+ def self.config
44
+ @config ||= Configuration.new
45
+ end
46
+
47
+ def self.environment
48
+ @environment
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,131 @@
1
+ module Sinatra
2
+ module Sprockets
3
+ class AssetPaths
4
+ attr_reader :config
5
+
6
+ class AssetNotPrecompiledError < StandardError; end
7
+
8
+ def initialize(config)
9
+ @config = config
10
+ end
11
+
12
+ def asset_for(source, ext)
13
+ source = source.to_s
14
+ return nil if is_uri?(source)
15
+ source = rewrite_extension(source, nil, ext)
16
+ config.environment[source]
17
+ rescue ::Sprockets::FileOutsidePaths
18
+ nil
19
+ end
20
+
21
+ def digest_for(logical_path)
22
+ if config.digest_assets? && config.digests && (digest = config.digests[logical_path])
23
+ digest
24
+ else
25
+ if config.compile_assets?
26
+ if config.digest_assets? && asset = config.environment[logical_path]
27
+ asset.digest_path
28
+ else
29
+ logical_path
30
+ end
31
+ else
32
+ raise AssetNotPrecompiledError.new("#{logical_path} isn't precompiled")
33
+ end
34
+ end
35
+ end
36
+
37
+ def compute_public_path(source, dir, options = {})
38
+ source = source.to_s
39
+ unless is_uri?(source)
40
+ source = rewrite_extension(source, dir, options[:ext]) if options[:ext]
41
+ source = rewrite_asset_path(source, dir, options)
42
+ source = rewrite_relative_url_root(source, config.relative_url_root)
43
+ source = rewrite_host_and_protocol(source, options[:protocol])
44
+ end
45
+ source
46
+ end
47
+
48
+ def is_uri?(path)
49
+ path =~ %r{^[-a-z]+://|^cid:|^//}
50
+ end
51
+
52
+ def rewrite_host_and_protocol(source, protocol = nil)
53
+ host = compute_asset_host(source)
54
+ if host && !is_uri?(host)
55
+ if (protocol || default_protocol) == :request && !has_request?
56
+ host = nil
57
+ else
58
+ host = "#{compute_protocol(protocol)}#{host}"
59
+ end
60
+ end
61
+ host ? "#{host}#{source}" : source
62
+ end
63
+
64
+ def rewrite_relative_url_root(source, relative_url_root)
65
+ relative_url_root && !source.starts_with?("#{relative_url_root}/") ? "#{relative_url_root}#{source}" : source
66
+ end
67
+
68
+ def rewrite_asset_path(source, dir, options = {})
69
+ if source[0] == ?/
70
+ source
71
+ else
72
+ source = digest_for(source) unless options[:digest] == false
73
+ source = File.join(dir, source)
74
+ source = "/#{source}" unless source =~ /^\//
75
+ source
76
+ end
77
+ end
78
+
79
+ def rewrite_extension(source, dir, ext)
80
+ if ext && File.extname(source).empty?
81
+ "#{source}.#{ext}"
82
+ else
83
+ source
84
+ end
85
+ end
86
+
87
+ def compute_asset_host(source)
88
+ if host = config.host
89
+ if host.respond_to?(:call)
90
+ args = [source]
91
+ arity = arity_of(host)
92
+ if arity > 1 && request.nil?
93
+ invalid_asset_host!("Remove the second argument to your asset_host Proc if you do not need the request.")
94
+ end
95
+ args << current_request if (arity > 1 || arity < 0) && has_request?
96
+ host.call(*args)
97
+ else
98
+ (host =~ /%d/) ? host % (Zlib.crc32(source) % 4) : host
99
+ end
100
+ end
101
+ end
102
+
103
+ def default_protocol
104
+ config.default_protocol || (request.nil?? :relative : :request)
105
+ end
106
+
107
+ def compute_protocol(protocol)
108
+ protocol ||= default_protocol
109
+ case protocol
110
+ when :request
111
+ if request.nil?
112
+ invalid_asset_host!("The protocol requested was :request. Consider using :relative instead.")
113
+ end
114
+ request.protocol
115
+ when :relative
116
+ "//"
117
+ else
118
+ "#{protocol}://"
119
+ end
120
+ end
121
+
122
+ def arity_of(callable)
123
+ callable.respond_to?(:arity) ? callable.arity : callable.method(:call).arity
124
+ end
125
+
126
+ def invalid_asset_host!(help_message)
127
+ raise ActionController::RoutingError, "This asset host cannot be computed without a request in scope. #{help_message}"
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,69 @@
1
+ module Sinatra
2
+ module Sprockets
3
+ class Configuration
4
+ DEFAULTS = {
5
+ :digest => true,
6
+ :debug => false,
7
+ :compile => false,
8
+ :compress => true,
9
+ :prefix => "assets",
10
+ :host => nil,
11
+ :relative_url_root => ENV['RACK_RELATIVE_URL_ROOT'],
12
+ :precompile => [ /\w+\.(?!js|css).+/, /application.(css|js)$/ ],
13
+ :manifest_path => "public/assets",
14
+ :app => nil
15
+ }
16
+ OPTIONS = DEFAULTS.keys
17
+
18
+ OPTIONS.each do |option|
19
+ define_method "#{option}=" do |value|
20
+ (@_config ||= {})[option] = value
21
+ end
22
+
23
+ define_method "#{option}" do
24
+ (@_config ||= {})[option]
25
+ end
26
+ end
27
+
28
+ [:digest, :debug, :compile, :compress].each do |option|
29
+ define_method "#{option}_assets?" do
30
+ !! @_config[option]
31
+ end
32
+ end
33
+
34
+ def initialize
35
+ @_config = DEFAULTS
36
+ @_digests = {}
37
+ @_paths = []
38
+ end
39
+
40
+ def digests
41
+ @_digests
42
+ end
43
+
44
+ def digests=(value)
45
+ @_digests = value
46
+ end
47
+
48
+ def append_path(path)
49
+ @_paths << path
50
+ end
51
+
52
+ def paths=(value)
53
+ @_paths = value.to_a
54
+ end
55
+
56
+ def paths
57
+ @_paths
58
+ end
59
+
60
+ def inspect
61
+ @_config.inspect
62
+ end
63
+
64
+ def environment
65
+ Sinatra::Sprockets.environment
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,152 @@
1
+ module Sinatra
2
+ module Sprockets
3
+ module Helpers
4
+ BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer
5
+ autoplay controls loop selected hidden scoped async
6
+ defer reversed ismap seemless muted required
7
+ autofocus novalidate formnovalidate open pubdate).to_set
8
+ BOOLEAN_ATTRIBUTES.merge(BOOLEAN_ATTRIBUTES.map {|attribute| attribute.to_sym })
9
+
10
+ def favicon_link_tag(source='favicon.ico', options={})
11
+ tag('link', {
12
+ :rel => 'shortcut icon',
13
+ :type => 'image/vnd.microsoft.icon',
14
+ :href => asset_path(source)
15
+ }.merge(options.symbolize_keys))
16
+ end
17
+
18
+ def image_tag(source, options = {})
19
+ options.symbolize_keys!
20
+
21
+ options[:src] = asset_path(source)
22
+
23
+ if size = options.delete(:size)
24
+ options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
25
+ end
26
+
27
+ tag("img", options)
28
+ end
29
+
30
+ def video_tag(sources, options = {})
31
+ options.symbolize_keys!
32
+
33
+ options[:poster] = asset_path(options[:poster]) if options[:poster]
34
+
35
+ if size = options.delete(:size)
36
+ options[:width], options[:height] = size.split("x") if size =~ %r{^\d+x\d+$}
37
+ end
38
+
39
+ if sources.is_a?(Array)
40
+ content_tag("video", options) do
41
+ sources.map { |source| tag("source", :src => source) }.join.html_safe
42
+ end
43
+ else
44
+ options[:src] = asset_path(sources)
45
+ tag("video", options)
46
+ end
47
+ end
48
+
49
+ def audio_tag(source, options = {})
50
+ options.symbolize_keys!
51
+ options[:src] = asset_path(source)
52
+ tag("audio", options)
53
+ end
54
+
55
+ def javascript_include_tag(*sources)
56
+ options = sources.extract_options!
57
+ debug = options.key?(:debug) ? options.delete(:debug) : config.debug_assets?
58
+ body = options.key?(:body) ? options.delete(:body) : false
59
+ digest = options.key?(:digest) ? options.delete(:digest) : config.digest_assets?
60
+
61
+ sources.collect do |source|
62
+ if debug && asset = asset_paths.asset_for(source, 'js')
63
+ asset.to_a.map { |dep|
64
+ src = asset_path(dep, :ext => 'js', :body => true, :digest => digest)
65
+ content_tag("script", "", { "type" => "application/javascript", "src" => src }.merge!(options))
66
+ }
67
+ else
68
+ src = asset_path(source, :ext => 'js', :body => body, :digest => digest)
69
+ content_tag("script", "", { "type" => "application/javascript", "src" => src }.merge!(options))
70
+ end
71
+ end.join("\n").html_safe
72
+ end
73
+
74
+ def stylesheet_link_tag(*sources)
75
+ options = sources.extract_options!
76
+ debug = options.key?(:debug) ? options.delete(:debug) : config.debug_assets?
77
+ body = options.key?(:body) ? options.delete(:body) : false
78
+ digest = options.key?(:digest) ? options.delete(:digest) : config.digest_assets?
79
+
80
+ sources.collect do |source|
81
+ if debug && asset = asset_paths.asset_for(source, 'css')
82
+ asset.to_a.map { |dep|
83
+ href = asset_path(dep, :ext => 'css', :body => true, :protocol => :request, :digest => digest)
84
+ tag("link", { "rel" => "stylesheet", "type" => "text/css", "media" => "screen", "href" => href }.merge!(options))
85
+ }
86
+ else
87
+ href = asset_path(source, :ext => 'css', :body => body, :protocol => :request, :digest => digest)
88
+ tag("link", { "rel" => "stylesheet", "type" => "text/css", "media" => "screen", "href" => href }.merge!(options))
89
+ end
90
+ end.join("\n").html_safe
91
+ end
92
+
93
+ def asset_path(source, options={})
94
+ source = source.logical_path if source.respond_to?(:logical_path)
95
+ path = asset_paths.compute_public_path(source, config.prefix, options.merge(:body => true))
96
+ options[:body] ? "#{path}?body=1" : path
97
+ end
98
+
99
+ def tag(name, options = nil, open = false, escape = true)
100
+ "<#{name}#{tag_options(options, escape) if options}#{open ? ">" : " />"}".html_safe
101
+ end
102
+
103
+ def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block)
104
+ if block_given?
105
+ options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash)
106
+ content_tag_string(name, block.call, options, escape)
107
+ else
108
+ content_tag_string(name, content_or_options_with_block, options, escape)
109
+ end
110
+ end
111
+
112
+ private
113
+
114
+ def asset_paths
115
+ @asset_paths ||= AssetPaths.new(Sinatra::Sprockets.config)
116
+ end
117
+
118
+ def config
119
+ Sinatra::Sprockets.config
120
+ end
121
+
122
+ def tag_options(options, escape = true)
123
+ unless options.blank?
124
+ attrs = []
125
+ options.each_pair do |key, value|
126
+ if key.to_s == 'data' && value.is_a?(Hash)
127
+ value.each do |k, v|
128
+ if !v.is_a?(String) && !v.is_a?(Symbol)
129
+ v = v.to_json
130
+ end
131
+ v = ERB::Util.html_escape(v) if escape
132
+ attrs << %(data-#{k.to_s.dasherize}="#{v}")
133
+ end
134
+ elsif BOOLEAN_ATTRIBUTES.include?(key)
135
+ attrs << %(#{key}="#{key}") if value
136
+ elsif !value.nil?
137
+ final_value = value.is_a?(Array) ? value.join(" ") : value
138
+ final_value = ERB::Util.html_escape(final_value) if escape
139
+ attrs << %(#{key}="#{final_value}")
140
+ end
141
+ end
142
+ " #{attrs.sort * ' '}".html_safe unless attrs.empty?
143
+ end
144
+ end
145
+
146
+ def content_tag_string(name, content, options, escape = true)
147
+ tag_options = tag_options(options, escape) if options
148
+ "<#{name}#{tag_options}>#{escape ? ERB::Util.h(content) : content}</#{name}>".html_safe
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,41 @@
1
+ require "fileutils"
2
+
3
+ namespace :assets do
4
+ desc "Compile all the assets named in config.assets.precompile"
5
+ task :precompile do
6
+ Rake::Task["assets:clean:all"].invoke
7
+ Rake::Task["assets:precompile:all"].invoke
8
+ end
9
+
10
+ namespace :precompile do
11
+ task :all => ["environment"] do
12
+ config = Sinatra::Sprockets.config
13
+ config.compile ||= true
14
+ config.digest ||= true
15
+ config.digests ||= {}
16
+
17
+ env = Sinatra::Sprockets.environment
18
+ target = File.join(config.app.settings.public_path, config.prefix)
19
+ compiler = Sinatra::Sprockets::StaticCompiler.new(env,
20
+ target,
21
+ config.precompile,
22
+ :manifest_path => config.manifest_path,
23
+ :digest => config.digest,
24
+ :manifest => true)
25
+ compiler.compile
26
+ end
27
+ end
28
+
29
+ desc "Remove compiled assets"
30
+ task :clean do
31
+ Rake::Task["assets:clean:all"].invoke
32
+ end
33
+
34
+ namespace :clean do
35
+ task :all => ["environment"] do
36
+ config = Sinatra::Sprockets.config
37
+ public_asset_path = File.join(config.app.settings.public_path, config.prefix)
38
+ rm_rf public_asset_path, :secure => true
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,64 @@
1
+ module Sinatra
2
+ module Sprockets
3
+ class StaticCompiler
4
+ require 'fileutils'
5
+ attr_accessor :env, :target, :paths
6
+
7
+ def initialize(env, target, paths, options = {})
8
+ @env = env
9
+ @target = target
10
+ @paths = paths
11
+ @digest = options.key?(:digest) ? options.delete(:digest) : true
12
+ @manifest = options.key?(:manifest) ? options.delete(:manifest) : true
13
+ @manifest_path = options.delete(:manifest_path) || target
14
+ end
15
+
16
+ def compile
17
+ manifest = {}
18
+ env.each_logical_path do |logical_path|
19
+ next unless compile_path?(logical_path)
20
+ if asset = env.find_asset(logical_path)
21
+ manifest[logical_path] = write_asset(asset)
22
+ end
23
+ end
24
+ write_manifest(manifest) if @manifest
25
+ end
26
+
27
+ def write_manifest(manifest)
28
+ FileUtils.mkdir_p(@manifest_path)
29
+ File.open("#{@manifest_path}/manifest.yml", 'wb') do |f|
30
+ YAML.dump(manifest, f)
31
+ end
32
+ end
33
+
34
+ def write_asset(asset)
35
+ path_for(asset).tap do |path|
36
+ filename = File.join(target, path)
37
+ FileUtils.mkdir_p File.dirname(filename)
38
+ asset.write_to(filename)
39
+ asset.write_to("#{filename}.gz") if filename.to_s =~ /\.(css|js)$/
40
+ end
41
+ end
42
+
43
+ def compile_path?(logical_path)
44
+ answer = false
45
+ paths.each do |path|
46
+ case path
47
+ when Regexp
48
+ answer = path.match(logical_path)
49
+ when Proc
50
+ answer = path.call(logical_path)
51
+ else
52
+ answer = File.fnmatch(path.to_s, logical_path)
53
+ end
54
+ break if answer
55
+ end
56
+ answer
57
+ end
58
+
59
+ def path_for(asset)
60
+ @digest ? asset.digest_path : asset.logical_path
61
+ end
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,5 @@
1
+ module Sinatra
2
+ module Sprockets
3
+ VERSION = "0.0.2.1"
4
+ end
5
+ end
@@ -0,0 +1,33 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "sinatra/sprockets/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "zaarly-sinatra-sprockets"
7
+ s.version = Sinatra::Sprockets::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["thegorgon", 'Alex Sharp', 'Justin Smestad']
10
+ s.email = ["jessereiss@gmail.com", "ajsharp@gmail.com", "justin.smestad@gmail.com"]
11
+ s.homepage = "http://github.com/zaarly/sinatra-sprockets"
12
+ s.summary = %q{Sinatra helpers for Sprockets integration.}
13
+ s.description = %q{Use Sprockets effectively with Sinatra.}
14
+
15
+ s.rubyforge_project = s.name
16
+
17
+ s.add_runtime_dependency 'sprockets', '~> 2.0.0'
18
+
19
+ s.files = [
20
+ "Gemfile",
21
+ "sinatra-sprockets.gemspec",
22
+ "lib/sinatra-sprockets.rb",
23
+ "lib/sinatra/sprockets.rb",
24
+ "lib/sinatra/sprockets/asset_paths.rb",
25
+ "lib/sinatra/sprockets/configuration.rb",
26
+ "lib/sinatra/sprockets/helpers.rb",
27
+ "lib/sinatra/sprockets/rake.rb",
28
+ "lib/sinatra/sprockets/static_compiler.rb",
29
+ "lib/sinatra/sprockets/version.rb"
30
+ ]
31
+
32
+ s.require_paths << "lib"
33
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: zaarly-sinatra-sprockets
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - thegorgon
9
+ - Alex Sharp
10
+ - Justin Smestad
11
+ autorequire:
12
+ bindir: bin
13
+ cert_chain: []
14
+ date: 2012-02-18 00:00:00.000000000 Z
15
+ dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: sprockets
18
+ requirement: &70198577580000 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 2.0.0
24
+ type: :runtime
25
+ prerelease: false
26
+ version_requirements: *70198577580000
27
+ description: Use Sprockets effectively with Sinatra.
28
+ email:
29
+ - jessereiss@gmail.com
30
+ - ajsharp@gmail.com
31
+ - justin.smestad@gmail.com
32
+ executables: []
33
+ extensions: []
34
+ extra_rdoc_files: []
35
+ files:
36
+ - Gemfile
37
+ - sinatra-sprockets.gemspec
38
+ - lib/sinatra-sprockets.rb
39
+ - lib/sinatra/sprockets.rb
40
+ - lib/sinatra/sprockets/asset_paths.rb
41
+ - lib/sinatra/sprockets/configuration.rb
42
+ - lib/sinatra/sprockets/helpers.rb
43
+ - lib/sinatra/sprockets/rake.rb
44
+ - lib/sinatra/sprockets/static_compiler.rb
45
+ - lib/sinatra/sprockets/version.rb
46
+ homepage: http://github.com/zaarly/sinatra-sprockets
47
+ licenses: []
48
+ post_install_message:
49
+ rdoc_options: []
50
+ require_paths:
51
+ - lib
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project: zaarly-sinatra-sprockets
67
+ rubygems_version: 1.8.15
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: Sinatra helpers for Sprockets integration.
71
+ test_files: []