tipsy 0.0.1 → 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +9 -0
- data/README.md +2 -2
- data/Rakefile +10 -0
- data/bin/tipsy +16 -5
- data/lib/tipsy.rb +26 -14
- data/lib/tipsy/application.rb +14 -16
- data/lib/tipsy/builder.rb +17 -4
- data/lib/tipsy/builders/base.rb +64 -0
- data/lib/tipsy/builders/export.rb +16 -0
- data/lib/tipsy/builders/project.rb +40 -0
- data/lib/tipsy/builders/remote.rb +14 -0
- data/lib/tipsy/compressors/css.rb +11 -0
- data/lib/tipsy/compressors/javascript.rb +25 -0
- data/lib/tipsy/helpers.rb +24 -1
- data/lib/tipsy/helpers/asset_paths.rb +19 -0
- data/lib/tipsy/helpers/asset_tags.rb +32 -0
- data/lib/tipsy/helpers/capture.rb +33 -0
- data/lib/tipsy/helpers/sass.rb +40 -0
- data/lib/tipsy/helpers/tag.rb +12 -0
- data/lib/tipsy/logger.rb +54 -3
- data/lib/tipsy/project/Gemfile +8 -0
- data/lib/tipsy/project/config.erb +5 -2
- data/lib/tipsy/sass/template.rb +137 -0
- data/lib/tipsy/server.rb +50 -7
- data/lib/tipsy/version.rb +1 -1
- data/lib/tipsy/view.rb +24 -10
- data/test/fixtures/about.html +1 -0
- data/test/fixtures/contact.html +1 -0
- data/test/fixtures/index.html +1 -0
- data/test/functional/page_test.rb +33 -0
- data/test/root/{assets → development/assets}/javascripts/test.js +0 -0
- data/test/root/{assets → development/assets}/stylesheets/screen.css.scss +0 -0
- data/test/root/{config.rb → development/config.rb} +0 -0
- data/test/root/{views → development/views}/_layout.html.erb +0 -0
- data/test/root/{views → development/views}/index.html.erb +0 -0
- data/test/root/test/assets/javascripts/test.js +0 -0
- data/test/root/test/assets/stylesheets/screen.css.scss +3 -0
- data/test/root/test/config.rb +6 -0
- data/test/root/test/views/_layout.html.erb +1 -0
- data/test/root/test/views/about/index.html +1 -0
- data/test/root/test/views/contact.html +1 -0
- data/test/root/test/views/index.html.erb +1 -0
- data/test/test_helper.rb +33 -0
- data/test/unit/helpers/asset_paths_test.rb +14 -0
- data/test/unit/helpers_test.rb +22 -0
- data/test/unit/server_test.rb +1 -0
- data/tipsy.gemspec +5 -4
- metadata +83 -35
- data/config.ru +0 -26
- data/lib/tipsy/generator.rb +0 -53
@@ -0,0 +1,32 @@
|
|
1
|
+
module Tipsy
|
2
|
+
module Helpers
|
3
|
+
module AssetTags
|
4
|
+
|
5
|
+
def image_tag(src, html_attrs = {})
|
6
|
+
html_attrs.stringify_keys!
|
7
|
+
html_attrs.reverse_merge!('alt' => File.basename(src))
|
8
|
+
tag(:img, html_attrs.merge('src' => asset_path(src)))
|
9
|
+
end
|
10
|
+
|
11
|
+
def javascript_include_tag(*files)
|
12
|
+
html_attrs = files.extract_options!
|
13
|
+
html_attrs.stringify_keys!
|
14
|
+
files.map{ |file|
|
15
|
+
content_tag('script', '', {'src' => asset_path(path_with_ext(file, 'js'))}.merge!(html_attrs))
|
16
|
+
}.join("\n")
|
17
|
+
end
|
18
|
+
|
19
|
+
def stylesheet_link_tag(*files)
|
20
|
+
html_attrs = files.extract_options!
|
21
|
+
html_attrs.reverse_merge!({
|
22
|
+
:media => "screen"
|
23
|
+
}).stringify_keys!
|
24
|
+
|
25
|
+
files.map{ |file|
|
26
|
+
content_tag('link', '', { 'href' => asset_path(path_with_ext(file, 'css')), 'rel' => "stylesheet" }.merge!(html_attrs))
|
27
|
+
}.join("\n")
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -17,6 +17,39 @@ module Tipsy
|
|
17
17
|
@_output_buffer = orig_buffer
|
18
18
|
end
|
19
19
|
|
20
|
+
def render(options = {})
|
21
|
+
options.symbolize_keys!
|
22
|
+
assert_valid_keys!(options, :template, :partial, :collection, :locals)
|
23
|
+
|
24
|
+
if template = options.delete(:template)
|
25
|
+
_render_template(template, options)
|
26
|
+
elsif template = options.delete(:partial)
|
27
|
+
_render_template(template, options, true)
|
28
|
+
else
|
29
|
+
raise 'Render requires a :template or :partial option.'
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def _render_template(name, options = {}, partial = false)
|
36
|
+
to_render = ( partial === true ? "_#{name}" : name )
|
37
|
+
to_render = view_trail.find(to_render)
|
38
|
+
unless to_render.nil?
|
39
|
+
local_vars = options.delete(:locals) || {}
|
40
|
+
results = Tilt[to_render].new(to_render, nil)
|
41
|
+
return results.render(self, local_vars)
|
42
|
+
end
|
43
|
+
raise "Missing #{ partial ? 'partial' : 'template' } #{name}."
|
44
|
+
end
|
45
|
+
|
46
|
+
def assert_valid_keys!(hash, *keys)
|
47
|
+
left = hash.keys.reject{ |k| keys.include?(k) }
|
48
|
+
unless left.empty?
|
49
|
+
raise 'Invalid keys for hash: #{left.join(", ")}'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
20
53
|
end
|
21
54
|
end
|
22
55
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'sass'
|
2
|
+
|
3
|
+
module Tipsy
|
4
|
+
module Helpers
|
5
|
+
module Sass
|
6
|
+
|
7
|
+
def asset_path(asset, kind)
|
8
|
+
::Sass::Script::String.new(public_path(asset.value, kind.value), true)
|
9
|
+
end
|
10
|
+
|
11
|
+
def asset_url(asset, kind)
|
12
|
+
::Sass::Script::String.new(%Q{url(#{public_path(asset.value, kind.value)})})
|
13
|
+
end
|
14
|
+
|
15
|
+
[:image, :font, :video, :audio, :javascript, :stylesheet].each do |asset_class|
|
16
|
+
class_eval %Q{
|
17
|
+
def #{asset_class}_path(asset)
|
18
|
+
asset_path(asset, Sass::Script::String.new("#{asset_class}"))
|
19
|
+
end
|
20
|
+
def #{asset_class}_url(asset)
|
21
|
+
asset_url(asset, Sass::Script::String.new("#{asset_class}"))
|
22
|
+
end
|
23
|
+
}, __FILE__, __LINE__ - 6
|
24
|
+
end
|
25
|
+
|
26
|
+
protected
|
27
|
+
def public_path(asset, kind)
|
28
|
+
options[:custom][:resolver].public_path(asset, kind.pluralize)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
module Sass
|
35
|
+
module Script
|
36
|
+
module Functions
|
37
|
+
include Tipsy::Helpers::Sass
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/tipsy/helpers/tag.rb
CHANGED
@@ -14,6 +14,18 @@ module Tipsy
|
|
14
14
|
"<#{name}#{make_attributes(html_attrs)}>#{content}</#{name}>"
|
15
15
|
end
|
16
16
|
|
17
|
+
def link_to(text, path, html_attrs = {})
|
18
|
+
content_tag(:a, text, html_attrs.merge!('href' => path))
|
19
|
+
end
|
20
|
+
|
21
|
+
def mail_to(addr, text = nil, html_attrs = {})
|
22
|
+
unless text || text.is_a?(Hash)
|
23
|
+
html_attrs = text if text
|
24
|
+
text = addr
|
25
|
+
end
|
26
|
+
link_to(text, "mailto:#{addr}", html_attrs)
|
27
|
+
end
|
28
|
+
|
17
29
|
private
|
18
30
|
|
19
31
|
def make_attributes(hash)
|
data/lib/tipsy/logger.rb
CHANGED
@@ -1,11 +1,62 @@
|
|
1
1
|
require 'logger'
|
2
2
|
|
3
3
|
module Tipsy
|
4
|
-
class Logger
|
4
|
+
class Logger
|
5
5
|
|
6
|
-
|
7
|
-
|
6
|
+
COLOR_VALUES = {
|
7
|
+
:clear => 0,
|
8
|
+
:red => 31,
|
9
|
+
:green => 32,
|
10
|
+
:yellow => 33
|
11
|
+
}
|
12
|
+
|
13
|
+
attr_accessor :cache
|
14
|
+
attr_reader :stdout
|
15
|
+
|
16
|
+
def initialize(o)
|
17
|
+
@stdout = o
|
18
|
+
@cache = []
|
8
19
|
end
|
9
20
|
|
21
|
+
def append(msg)
|
22
|
+
@cache << msg
|
23
|
+
end
|
24
|
+
|
25
|
+
def flush!
|
26
|
+
cache.each{ |c| print c }
|
27
|
+
end
|
28
|
+
|
29
|
+
def log_action(name, action)
|
30
|
+
print colorize(:green, (name.rjust(12, ' ') << " "), :clear, action)
|
31
|
+
end
|
32
|
+
|
33
|
+
def info(msg)
|
34
|
+
print msg
|
35
|
+
end
|
36
|
+
|
37
|
+
def warn(msg)
|
38
|
+
print colorize(:yellow, "Warning: ", :clear, msg)
|
39
|
+
end
|
40
|
+
|
41
|
+
def error
|
42
|
+
print colorize(:red, "Error: ", :clear, msg)
|
43
|
+
end
|
44
|
+
|
45
|
+
def colorize(*args)
|
46
|
+
output = args.inject([]) do |arr, option|
|
47
|
+
unless option.is_a?(Symbol) && COLOR_VALUES[option]
|
48
|
+
arr << option
|
49
|
+
else
|
50
|
+
arr << "\e[#{COLOR_VALUES[option]}m"
|
51
|
+
end
|
52
|
+
arr
|
53
|
+
end
|
54
|
+
output.push("\e[0m").join("")
|
55
|
+
end
|
56
|
+
|
57
|
+
def print(msg)
|
58
|
+
puts msg
|
59
|
+
end
|
60
|
+
|
10
61
|
end
|
11
62
|
end
|
@@ -1,8 +1,11 @@
|
|
1
1
|
class <%= classname %> < Tipsy::Application
|
2
2
|
|
3
3
|
# Configure assets to be precompiled
|
4
|
-
config.assets << "site.js"
|
5
|
-
config.assets << "screen.css"
|
4
|
+
config.assets.precompile << "site.js"
|
5
|
+
config.assets.precompile << "screen.css"
|
6
|
+
|
7
|
+
# Add assets to the load path
|
8
|
+
# config.assets.paths << "/some/path"
|
6
9
|
|
7
10
|
# The path where build files will go when compiled
|
8
11
|
# config.build_path = <%= File.join(root, 'build') %>
|
@@ -0,0 +1,137 @@
|
|
1
|
+
require 'tilt'
|
2
|
+
require 'sass/engine'
|
3
|
+
require 'compass'
|
4
|
+
|
5
|
+
##
|
6
|
+
# Most of this was extracted and modified from the sass-rails plugin, since most of the
|
7
|
+
# Sprockets functionality is the same.
|
8
|
+
#
|
9
|
+
module Tipsy
|
10
|
+
module Sass
|
11
|
+
class Template < Tilt::ScssTemplate
|
12
|
+
self.default_mime_type = 'text/css'
|
13
|
+
|
14
|
+
class Resolver
|
15
|
+
attr_accessor :context
|
16
|
+
def initialize(context)
|
17
|
+
@context = context
|
18
|
+
end
|
19
|
+
def resolve(path, content_type = :self)
|
20
|
+
options = {}
|
21
|
+
options[:content_type] = content_type unless content_type.nil?
|
22
|
+
context.resolve(path, options)
|
23
|
+
rescue Sprockets::FileNotFound, Sprockets::ContentTypeMismatch
|
24
|
+
nil
|
25
|
+
end
|
26
|
+
def public_path(path, scope)
|
27
|
+
context.asset_paths.compute_public_path(path, scope)
|
28
|
+
end
|
29
|
+
def process(path)
|
30
|
+
context.environment[path].to_s
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
|
35
|
+
class Importer
|
36
|
+
|
37
|
+
GLOB = /\*|\[.+\]/
|
38
|
+
PARTIAL = /^_/
|
39
|
+
HAS_EXTENSION = /\.css(.s[ac]ss)?$/
|
40
|
+
SASS_EXTENSIONS = {
|
41
|
+
".css.sass" => :sass,
|
42
|
+
".css.scss" => :scss,
|
43
|
+
".sass" => :sass,
|
44
|
+
".scss" => :scss
|
45
|
+
}
|
46
|
+
|
47
|
+
attr_reader :context
|
48
|
+
|
49
|
+
def initialize(context)
|
50
|
+
@context = context
|
51
|
+
@resolver = Resolver.new(context)
|
52
|
+
end
|
53
|
+
|
54
|
+
def sass_file?(filename)
|
55
|
+
filename = filename.to_s
|
56
|
+
SASS_EXTENSIONS.keys.any?{|ext| filename[ext]}
|
57
|
+
end
|
58
|
+
|
59
|
+
def syntax(filename)
|
60
|
+
filename = filename.to_s
|
61
|
+
SASS_EXTENSIONS.each {|ext, syntax| return syntax if filename[(ext.size+2)..-1][ext]}
|
62
|
+
nil
|
63
|
+
end
|
64
|
+
|
65
|
+
def render_with_engine(data, pathname, options = {})
|
66
|
+
::Sass::Engine.new(data, options.merge(:filename => pathname.to_s, :importer => self, :syntax => syntax(pathname)))
|
67
|
+
end
|
68
|
+
|
69
|
+
def resolve(name, base_pathname = nil)
|
70
|
+
name = Pathname.new(name)
|
71
|
+
if base_pathname && base_pathname.to_s.size > 0
|
72
|
+
root = Pathname.new(context.root_path)
|
73
|
+
name = base_pathname.relative_path_from(root).join(name)
|
74
|
+
end
|
75
|
+
partial_name = name.dirname.join("_#{name.basename}")
|
76
|
+
@resolver.resolve(name) || @resolver.resolve(partial_name)
|
77
|
+
end
|
78
|
+
|
79
|
+
def find_relative(name, base, options)
|
80
|
+
base_pathname = Pathname.new(base)
|
81
|
+
if pathname = resolve(name, base_pathname.dirname)
|
82
|
+
context.depend_on(pathname)
|
83
|
+
if sass_file?(pathname)
|
84
|
+
render_with_engine(pathname.read, pathname)
|
85
|
+
else
|
86
|
+
render_with_engine(@resolver.process(pathname), pathname)
|
87
|
+
end
|
88
|
+
else
|
89
|
+
nil
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def find(name, options)
|
94
|
+
if pathname = resolve(name)
|
95
|
+
context.depend_on(pathname)
|
96
|
+
if sass_file?(pathname)
|
97
|
+
render_with_engine(pathname.read, pathname)
|
98
|
+
else
|
99
|
+
render_with_engine(@resolver.process(pathname), pathname)
|
100
|
+
end
|
101
|
+
else
|
102
|
+
nil
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def mtime(name, options)
|
107
|
+
if pathname = resolve_sass_path(name, options)
|
108
|
+
pathname.mtime
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def key(name, options)
|
113
|
+
["Sprockets:" + File.dirname(File.expand_path(name)), File.basename(name)]
|
114
|
+
end
|
115
|
+
|
116
|
+
def resolve_sass_path(name, options = {}, relative = false)
|
117
|
+
prefix = ( relative === false ? "" : "./" )
|
118
|
+
(context.resolve("#{prefix}#{name}", options) || context.resolve("#{prefix}_#{name}", options))
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
def prepare
|
124
|
+
end
|
125
|
+
|
126
|
+
def evaluate(scope, locals, &block)
|
127
|
+
::Sass::Engine.new(data, {
|
128
|
+
:filename => eval_file,
|
129
|
+
:line => line,
|
130
|
+
:syntax => :scss,
|
131
|
+
:importer => Importer.new(scope)
|
132
|
+
}.reverse_merge!(::Compass.sass_engine_options)).render
|
133
|
+
end
|
134
|
+
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
data/lib/tipsy/server.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
require 'rack'
|
2
2
|
require 'sprockets'
|
3
3
|
require 'hike'
|
4
|
-
require 'sass'
|
5
4
|
|
6
5
|
module Tipsy
|
7
6
|
|
@@ -9,6 +8,19 @@ module Tipsy
|
|
9
8
|
|
10
9
|
attr_reader :request
|
11
10
|
attr_reader :response
|
11
|
+
|
12
|
+
def self.init!
|
13
|
+
Rack::Builder.new {
|
14
|
+
use Rack::CommonLogger
|
15
|
+
use Rack::ShowStatus
|
16
|
+
use Rack::ShowExceptions
|
17
|
+
use Tipsy::StaticFile, :root => Tipsy.options.public_path, :urls => %w[/]
|
18
|
+
run Rack::Cascade.new([
|
19
|
+
Rack::URLMap.new({ "/#{File.basename(Tipsy.options.asset_path)}" => Tipsy::AssetHandler.new }),
|
20
|
+
Tipsy::Server.new
|
21
|
+
])
|
22
|
+
}
|
23
|
+
end
|
12
24
|
|
13
25
|
def initialize
|
14
26
|
@last_update = Time.now
|
@@ -37,14 +49,45 @@ module Tipsy
|
|
37
49
|
|
38
50
|
class AssetHandler < Sprockets::Environment
|
39
51
|
def initialize
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
52
|
+
Sprockets.register_engine '.scss', Tipsy::Sass::Template
|
53
|
+
|
54
|
+
super(Tipsy.root) do |env|
|
55
|
+
env.static_root = Tipsy.options.asset_path
|
56
|
+
#env.css_compressor = Tipsy::Compressors::CssCompressor.new
|
57
|
+
# begin
|
58
|
+
# require 'uglifier'
|
59
|
+
# env.js_compressor = Uglifier
|
60
|
+
# rescue LoadError
|
61
|
+
# env.js_compressor = Tipsy::Compressors::JavascriptCompressor.new
|
62
|
+
# end
|
63
|
+
end
|
64
|
+
Tipsy.sprockets = self
|
65
|
+
configure_paths!
|
46
66
|
self
|
47
67
|
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def configure_paths!
|
72
|
+
require 'compass'
|
73
|
+
require 'sass/plugin'
|
74
|
+
|
75
|
+
append_path "assets/javascripts"
|
76
|
+
append_path "assets/images"
|
77
|
+
append_path "assets/stylesheets"
|
78
|
+
|
79
|
+
compass_config = ::Compass::Configuration::Data.new("project")
|
80
|
+
compass_config.project_type = :rails
|
81
|
+
compass_config.project_path = Tipsy.root
|
82
|
+
compass_config.extensions_dir = Tipsy.root
|
83
|
+
compass_config.sass_dir = File.join("assets", "stylesheets")
|
84
|
+
|
85
|
+
::Sass::Plugin.engine_options.merge!(Compass.sass_engine_options)
|
86
|
+
|
87
|
+
Tipsy.options.assets.paths |= self.paths
|
88
|
+
|
89
|
+
end
|
90
|
+
|
48
91
|
end
|
49
92
|
|
50
93
|
# From the rack/contrib TryStatic class
|
data/lib/tipsy/version.rb
CHANGED