tipsy 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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