big_band 0.2.1
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/LICENSE +27 -0
- data/README.rdoc +303 -0
- data/README.rdoc.erb +39 -0
- data/Rakefile +129 -0
- data/big_band.gemspec +29 -0
- data/example/example.rb +13 -0
- data/example/views/index.haml +8 -0
- data/example/views/layout.haml +2 -0
- data/example/views/stylesheets/_base.sass +1 -0
- data/example/views/stylesheets/screen.sass +12 -0
- data/lib/big_band/advanced_routes.rb +184 -0
- data/lib/big_band/basic_extensions.rb +176 -0
- data/lib/big_band/compass/big_band.rb +4 -0
- data/lib/big_band/compass/stylesheets/_big_band.sass +1 -0
- data/lib/big_band/compass/stylesheets/big_band/_blueprint.sass +1 -0
- data/lib/big_band/compass/stylesheets/big_band/_utilities.sass +6 -0
- data/lib/big_band/compass/stylesheets/big_band/blueprint/_html5.sass +4 -0
- data/lib/big_band/compass/stylesheets/big_band/layouts/_inspector.sass +103 -0
- data/lib/big_band/compass/stylesheets/big_band/utilities/_border_radius.sass +27 -0
- data/lib/big_band/compass/stylesheets/big_band/utilities/_css3_prefix.sass +14 -0
- data/lib/big_band/compass/stylesheets/big_band/utilities/_fancy_buttons.sass +62 -0
- data/lib/big_band/compass/stylesheets/big_band/utilities/_html5.sass +3 -0
- data/lib/big_band/compass.rb +94 -0
- data/lib/big_band/files/overlay-button.png +0 -0
- data/lib/big_band/integration/bacon.rb +10 -0
- data/lib/big_band/integration/monk.rb +26 -0
- data/lib/big_band/integration/rake.rb +60 -0
- data/lib/big_band/integration/rspec.rb +11 -0
- data/lib/big_band/integration/test/spec.rb +2 -0
- data/lib/big_band/integration/test/unit.rb +2 -0
- data/lib/big_band/integration/test.rb +42 -0
- data/lib/big_band/integration/test_spec.rb +8 -0
- data/lib/big_band/integration/test_unit.rb +10 -0
- data/lib/big_band/integration/yard.rb +104 -0
- data/lib/big_band/integration.rb +42 -0
- data/lib/big_band/more_helpers.rb +50 -0
- data/lib/big_band/more_server/rainbows.rb +13 -0
- data/lib/big_band/more_server/unicorn.rb +28 -0
- data/lib/big_band/more_server.rb +14 -0
- data/lib/big_band/reloader.rb +113 -0
- data/lib/big_band/sass.rb +28 -0
- data/lib/big_band/version.rb +3 -0
- data/lib/big_band/web_inspector.rb +178 -0
- data/lib/big_band.rb +239 -0
- data/lib/big_bang.rb +6 -0
- data/lib/yard-sinatra.rb +2 -0
- data/spec/big_band/advanced_routes_spec.rb +70 -0
- data/spec/big_band/basic_extensions_spec.rb +39 -0
- data/spec/big_band/more_server_spec.rb +7 -0
- data/spec/big_band/sass_spec.rb +21 -0
- data/spec/spec.opts +5 -0
- data/spec/spec_helper.rb +4 -0
- data/yard-sinatra.gemspec +24 -0
- metadata +167 -0
@@ -0,0 +1,184 @@
|
|
1
|
+
require "sinatra/base"
|
2
|
+
|
3
|
+
class BigBand < Sinatra::Base
|
4
|
+
|
5
|
+
# AdvancedRoutes makes routes first class objects in Sinatra:
|
6
|
+
#
|
7
|
+
# require "sinatra"
|
8
|
+
# require "big_band"
|
9
|
+
#
|
10
|
+
# admin_route = get "/admin" do
|
11
|
+
# administrate_stuff
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# before do
|
15
|
+
# # Let's deactivate the route if we have no password file.
|
16
|
+
# if File.exists? "admin_password"
|
17
|
+
# admin_route.activate
|
18
|
+
# else
|
19
|
+
# admin_route.deactivate
|
20
|
+
# end
|
21
|
+
# end
|
22
|
+
#
|
23
|
+
# first_route = get "/:name" do
|
24
|
+
# # stuff
|
25
|
+
# end
|
26
|
+
#
|
27
|
+
# other_route = get "/foo_:name" do
|
28
|
+
# # other stuff
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# # Unfortunatly first_route will catch all the requests other_route would
|
32
|
+
# # have gotten, since it has been defined first. But wait, we can fix this!
|
33
|
+
# other_route.promote
|
34
|
+
module AdvancedRoutes
|
35
|
+
|
36
|
+
module ArrayMethods
|
37
|
+
::Array.send :include, self
|
38
|
+
|
39
|
+
def to_route(verb, args = {})
|
40
|
+
dup.to_route! verb, args
|
41
|
+
end
|
42
|
+
|
43
|
+
def to_route!(verb, args = {})
|
44
|
+
extend BigBand::AdvancedRoutes::Route
|
45
|
+
self.verb = verb
|
46
|
+
args.each do |key, value|
|
47
|
+
send "#{key}=", value
|
48
|
+
end
|
49
|
+
self
|
50
|
+
end
|
51
|
+
|
52
|
+
def signature
|
53
|
+
self
|
54
|
+
end
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
module Route
|
59
|
+
|
60
|
+
attr_accessor :app, :verb, :file, :line, :path
|
61
|
+
|
62
|
+
def pattern; self[0]; end
|
63
|
+
def keys; self[1]; end
|
64
|
+
def conditions; self[2]; end
|
65
|
+
def block; self[3]; end
|
66
|
+
alias to_proc block
|
67
|
+
|
68
|
+
def pattern=(value); self[0] = value; end
|
69
|
+
def keys=(value); self[1] = value; end
|
70
|
+
def conditions=(value); self[2] = value; end
|
71
|
+
def block=(value); self[3] = value; end
|
72
|
+
|
73
|
+
def signature
|
74
|
+
[pattern, keys, conditions, block]
|
75
|
+
end
|
76
|
+
|
77
|
+
def active?
|
78
|
+
app.routes[verb].include? self
|
79
|
+
end
|
80
|
+
|
81
|
+
def activate(at_top = false)
|
82
|
+
also_change.each { |r| r.activate }
|
83
|
+
return if active?
|
84
|
+
meth = at_top ? :unshift : :push
|
85
|
+
(app.routes[verb] ||= []).send(meth, self)
|
86
|
+
invoke_hook :route_added, verb, path, block
|
87
|
+
invoke_hook :advanced_root_activated, self
|
88
|
+
self
|
89
|
+
end
|
90
|
+
|
91
|
+
def deactivate
|
92
|
+
also_change.each { |r| r.deactivate }
|
93
|
+
return unless active?
|
94
|
+
(app.routes[verb] ||= []).delete(signature)
|
95
|
+
invoke_hook :route_removed, verb, path, block
|
96
|
+
invoke_hook :advanced_root_deactivated, self
|
97
|
+
self
|
98
|
+
end
|
99
|
+
|
100
|
+
def promote(upwards = true)
|
101
|
+
also_change.each { |r| r.promote(upwards) }
|
102
|
+
deactivate
|
103
|
+
activate(upwards)
|
104
|
+
end
|
105
|
+
|
106
|
+
def file?
|
107
|
+
!!@file
|
108
|
+
end
|
109
|
+
|
110
|
+
def inspect
|
111
|
+
"#<BigBand::AdvancedRoutes::Route #{ivar_inspect.join ", "}>"
|
112
|
+
end
|
113
|
+
|
114
|
+
def to_route(verb, args = {})
|
115
|
+
args = args.dup
|
116
|
+
[:app, :verb, :file, :line, :path].each { |key| args[key] ||= send(key) }
|
117
|
+
super(verb, args)
|
118
|
+
end
|
119
|
+
|
120
|
+
def also_change(*other_routes)
|
121
|
+
(@also_change ||= []).push(*other_routes)
|
122
|
+
end
|
123
|
+
|
124
|
+
private
|
125
|
+
|
126
|
+
def ivar_inspect
|
127
|
+
[:signature, :verb, :app, :file, :line].map do |var|
|
128
|
+
value = send(var)
|
129
|
+
"@#{var}=#{value.inspect}" unless value.nil?
|
130
|
+
end.compact
|
131
|
+
end
|
132
|
+
|
133
|
+
def invoke_hook(*args)
|
134
|
+
app.send(:invoke_hook, *args)
|
135
|
+
end
|
136
|
+
|
137
|
+
end
|
138
|
+
|
139
|
+
module ClassMethods
|
140
|
+
|
141
|
+
def get(path, opts={}, &block)
|
142
|
+
first_route, *other_routes = capture_routes { super }
|
143
|
+
first_route.also_change(*other_routes)
|
144
|
+
first_route
|
145
|
+
end
|
146
|
+
|
147
|
+
def route(verb, path, options={}, &block)
|
148
|
+
file, line = block.source_location if block.respond_to? :source_location
|
149
|
+
file ||= caller_files.first
|
150
|
+
route = super(verb, path, options, &block)
|
151
|
+
route.to_route! verb, :app => self, :file => file.expand_path, :line => line, :path => path
|
152
|
+
invoke_hook :advanced_root_added, route
|
153
|
+
@capture_routes << route if @capture_routes
|
154
|
+
route
|
155
|
+
end
|
156
|
+
|
157
|
+
def each_route(&block)
|
158
|
+
return enum_for(:each_route) if respond_to? :enum_for and not block
|
159
|
+
routes.inject([]) { |result, (verb, list)| result.push *list.each(&block) }
|
160
|
+
end
|
161
|
+
|
162
|
+
private
|
163
|
+
|
164
|
+
def capture_routes
|
165
|
+
capture_routes_was, @capture_routes = @capture_routes, []
|
166
|
+
yield
|
167
|
+
captured, @capture_routes = @capture_routes, capture_routes_was
|
168
|
+
captured
|
169
|
+
end
|
170
|
+
|
171
|
+
end
|
172
|
+
|
173
|
+
def self.registered(klass)
|
174
|
+
klass.extend ClassMethods
|
175
|
+
klass.routes.each do |verb, routes|
|
176
|
+
routes.each do |route|
|
177
|
+
route.to_route! verb, :app => klass
|
178
|
+
klass.send :invoke_hook, :advanced_root_added, route
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
end
|
184
|
+
end
|
@@ -0,0 +1,176 @@
|
|
1
|
+
require "sinatra/base"
|
2
|
+
require "monkey-lib"
|
3
|
+
|
4
|
+
class BigBand < Sinatra::Base
|
5
|
+
|
6
|
+
CALLERS_TO_IGNORE = (class << Sinatra::Base; CALLERS_TO_IGNORE; end) unless defined? CALLERS_TO_IGNORE
|
7
|
+
Dir.chdir __FILE__.dirname.dirname do
|
8
|
+
Dir.glob("**/*.rb") { |file| CALLERS_TO_IGNORE << Regexp.new(Regexp.escape(file)) }
|
9
|
+
end
|
10
|
+
|
11
|
+
# Basic Sinatra extension (mainly extending Sinatra's standard methods, like set or register).
|
12
|
+
# Also it features a more advanced path guessing than Sinatra::Base.
|
13
|
+
# Normally you do not have to register this module manually, as the other extensions will do so
|
14
|
+
# if necessary.
|
15
|
+
module BasicExtensions
|
16
|
+
module ClassMethods
|
17
|
+
|
18
|
+
attr_writer :root, :guessed_root
|
19
|
+
|
20
|
+
# More advanced set:
|
21
|
+
# - Adds set_#{key} and set_value hooks to set.
|
22
|
+
# - Merges the old value with the new one, if both are hashes:
|
23
|
+
# set :haml, :format => :html5, :escape_html => true
|
24
|
+
# set :haml, :excape_html => false
|
25
|
+
# haml # => { :format => :html5, :escape_html => false }
|
26
|
+
# - Allowes passing a block:
|
27
|
+
# set(:foo) { Time.now }
|
28
|
+
# - Defines a helper to access #{key} and #{key}? unless a helper/method with that name already exists.
|
29
|
+
def set(key, value = self, &block)
|
30
|
+
# FIXME: refactor, refactor, refactor
|
31
|
+
if block_given?
|
32
|
+
raise ArgumentError, "both a value and a block given" if value != self
|
33
|
+
value = block
|
34
|
+
end
|
35
|
+
symbolized = (key.to_sym if key.respond_to? :to_sym)
|
36
|
+
old_value = (send(symbolized) if symbolized and respond_to? symbolized)
|
37
|
+
value = old_value.merge value if value.is_a? Hash and old_value.is_a? Hash
|
38
|
+
super(key, value)
|
39
|
+
if symbolized
|
40
|
+
method_names = instance_methods.map { |m| m.to_s }
|
41
|
+
define_method(key) { self.class.send(key) } unless method_names.include? key.to_s
|
42
|
+
define_method("#{key}?") { self.class.send("#{key}?") } unless method_names.include? "#{key}?"
|
43
|
+
end
|
44
|
+
# HACK: Sinatra::Base.set uses recursion and in the final step value always
|
45
|
+
# is a Proc. Also, if value is a Proc no step ever follows. I abuse this to
|
46
|
+
# invoke the hooks only once per set.
|
47
|
+
if value.is_a? Proc
|
48
|
+
invoke_hook "set_#{key}", self
|
49
|
+
invoke_hook :set_value, self, key
|
50
|
+
end
|
51
|
+
self
|
52
|
+
end
|
53
|
+
|
54
|
+
# More advacend register:
|
55
|
+
# - If an exntesion is registered twice, the registered hook will only be called once.
|
56
|
+
def register(*extensions, &block)
|
57
|
+
extensions.reject! { |e| self.extensions.include? e }
|
58
|
+
super(*extensions, &block)
|
59
|
+
end
|
60
|
+
|
61
|
+
# Short hand so you can skip those ugly File.expand_path(File.join(File.dirname(__FILE__), ...))
|
62
|
+
# lines.
|
63
|
+
def root_path(*args)
|
64
|
+
relative = File.join(*args)
|
65
|
+
return relative if relative.expand_path == relative
|
66
|
+
root.expand_path / relative
|
67
|
+
end
|
68
|
+
|
69
|
+
# Like root_path, but does return an array instead of a string. Optionally takes a block that will
|
70
|
+
# be called for each entry once.
|
71
|
+
#
|
72
|
+
# Example:
|
73
|
+
# class Foo < BigBand
|
74
|
+
# root_glob("app", "{models,views,controllers}", "*.rb") { |file| load file }
|
75
|
+
# end
|
76
|
+
def root_glob(*args, &block)
|
77
|
+
Dir.glob(root_path(*args), &block)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Whether or not to start a webserver.
|
81
|
+
def run?
|
82
|
+
@run ||= true
|
83
|
+
@run and !@running and app_file? and $0.expand_path == app_file.expand_path
|
84
|
+
end
|
85
|
+
|
86
|
+
# Disable automatically running this class as soon it is subclassed.
|
87
|
+
def inherited
|
88
|
+
super
|
89
|
+
@run = false
|
90
|
+
end
|
91
|
+
|
92
|
+
# The application's root directory. BigBand will guess if missing.
|
93
|
+
def root
|
94
|
+
return ".".expand_path unless app_file?
|
95
|
+
return @root if @root
|
96
|
+
@guessed_root ||= begin
|
97
|
+
dir = app_file.expand_path.dirname
|
98
|
+
if dir.basename == "lib" and not (dir / "lib").directory?
|
99
|
+
dir.dirname
|
100
|
+
else
|
101
|
+
dir
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
# Returns true if the #root is known.
|
107
|
+
def root?
|
108
|
+
!!@root || app_file?
|
109
|
+
end
|
110
|
+
|
111
|
+
# Option parser for #run!
|
112
|
+
def run_option_parser
|
113
|
+
@run_option_parser ||= begin
|
114
|
+
require 'optparse'
|
115
|
+
OptionParser.new do |op|
|
116
|
+
op.on('-x') { set :lock, true }
|
117
|
+
op.on('-e env') { |val| set :environment, val.to_sym }
|
118
|
+
op.on('-s server') { |val| set :server, val }
|
119
|
+
op.on('-p port') { |val| set :port, val.to_i }
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
# Extended #run!, offers an extandable option parser for
|
125
|
+
# BigBand with the same standard options as the one of
|
126
|
+
# Sinatra#Default (see #run_option_parser).
|
127
|
+
def run!(options = {})
|
128
|
+
run_option_parser.parse!(ARGV.dup) unless ARGV.empty?
|
129
|
+
@running = true
|
130
|
+
super(options)
|
131
|
+
end
|
132
|
+
|
133
|
+
end
|
134
|
+
|
135
|
+
module InstanceMethods
|
136
|
+
|
137
|
+
# See BigBand::BasicExtentions::ClassMethods#root_path
|
138
|
+
def root_path(*args)
|
139
|
+
self.class.root_path(*args)
|
140
|
+
end
|
141
|
+
|
142
|
+
# See BigBand::BasicExtentions::ClassMethods#root_path
|
143
|
+
def root_glob(*args, &block)
|
144
|
+
self.class.root_glob(*args, &block)
|
145
|
+
end
|
146
|
+
|
147
|
+
# See BigBand::BasicExtentions::ClassMethods#root
|
148
|
+
def root
|
149
|
+
self.class.root
|
150
|
+
end
|
151
|
+
|
152
|
+
# See BigBand::BasicExtentions::ClassMethods#root?
|
153
|
+
def root?
|
154
|
+
self.class.root
|
155
|
+
end
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
def self.registered(klass)
|
160
|
+
klass.set :app_file, klass.caller_files.first.expand_path unless klass.app_file?
|
161
|
+
klass.extend ClassMethods
|
162
|
+
klass.send :include, InstanceMethods
|
163
|
+
klass.set :haml, :format => :html5, :escape_html => true
|
164
|
+
klass.use Rack::Session::Cookie
|
165
|
+
klass.enable :sessions
|
166
|
+
klass.get %r{/__big_band__/([^\.]+(\.[^\.]+)?)} do
|
167
|
+
send_file(__FILE__.expand_path.dirname / :files / params[:captures].first)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
def self.set_app_file(klass)
|
172
|
+
klass.guessed_root = nil
|
173
|
+
end
|
174
|
+
|
175
|
+
end
|
176
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
@import big_band/utilities.sass
|
@@ -0,0 +1 @@
|
|
1
|
+
@import blueprint/html5.sass
|
@@ -0,0 +1,103 @@
|
|
1
|
+
@import ../utilities.sass
|
2
|
+
@import blueprint.sass
|
3
|
+
@import blueprint/screen.sass
|
4
|
+
@import blueprint/modules/fancy_type.sass
|
5
|
+
@import blueprint/modules/scaffolding.sass
|
6
|
+
@import blueprint/modules/typography.sass
|
7
|
+
|
8
|
+
=layout_inspector
|
9
|
+
+html5
|
10
|
+
+blueprint-typography
|
11
|
+
+fancy-paragraphs
|
12
|
+
body
|
13
|
+
padding: 5em 1em
|
14
|
+
background-color: #ddd
|
15
|
+
color
|
16
|
+
header
|
17
|
+
+box-shadow(0 2px 15px rgba(0, 0, 0, 0.8))
|
18
|
+
padding: 0px 10px
|
19
|
+
text-align: right
|
20
|
+
font-size: 80%
|
21
|
+
background:
|
22
|
+
color: rgba(0, 0, 0, 0.5)
|
23
|
+
image: url(/__big_band__/overlay-button.png)
|
24
|
+
repeat: repeat-x
|
25
|
+
border-bottom: solid 2px #333
|
26
|
+
color: #333
|
27
|
+
position: fixed
|
28
|
+
top: 0
|
29
|
+
right: 0
|
30
|
+
width: 100%
|
31
|
+
nav
|
32
|
+
a
|
33
|
+
+fancy-button-link(#040, 20px, 100px)
|
34
|
+
margin: 5px
|
35
|
+
h1
|
36
|
+
font:
|
37
|
+
weight: 500
|
38
|
+
size: 40px
|
39
|
+
margin: 0px
|
40
|
+
float: left
|
41
|
+
padding-left: 20px
|
42
|
+
color: #333
|
43
|
+
text-shadow: 0px 1px 2px rgba(0,0,0,0.8), -1px -1px 3px #eee, 0px 0px 8px rgba(0,0,0,0.7)
|
44
|
+
h2
|
45
|
+
font:
|
46
|
+
weight: bold
|
47
|
+
size: 130%
|
48
|
+
border-bottom: dotted 1px #bbb
|
49
|
+
width: 500px
|
50
|
+
table
|
51
|
+
+box-shadow(0px 3px 10px rgba(0,0,0,0.7))
|
52
|
+
border: solid 1px #555
|
53
|
+
background:
|
54
|
+
color: #fff
|
55
|
+
image: url(/__big_band__/overlay-button.png)
|
56
|
+
padding: 0px
|
57
|
+
width: 80%
|
58
|
+
margin: 0px 10%
|
59
|
+
tr
|
60
|
+
th, td
|
61
|
+
padding:
|
62
|
+
bottom: 0
|
63
|
+
top: 0
|
64
|
+
left: 5px
|
65
|
+
right: 20px
|
66
|
+
th
|
67
|
+
background-color: #555
|
68
|
+
color: #fff
|
69
|
+
font:
|
70
|
+
weight: bold
|
71
|
+
size: 90%
|
72
|
+
td
|
73
|
+
border:
|
74
|
+
color: #ddd
|
75
|
+
style: solid
|
76
|
+
width: 0px
|
77
|
+
left-width: 1px
|
78
|
+
min-width: 80px
|
79
|
+
footer
|
80
|
+
margin-top: 20px
|
81
|
+
+alt
|
82
|
+
a
|
83
|
+
color: #040
|
84
|
+
text-decoration: none
|
85
|
+
&:hover, &:visited
|
86
|
+
color: #040
|
87
|
+
&:hover
|
88
|
+
text-decoration: underline
|
89
|
+
.note
|
90
|
+
+box-shadow(0px 3px 10px rgba(0,0,0,0.7))
|
91
|
+
+border-radius
|
92
|
+
margin:
|
93
|
+
top: 5px
|
94
|
+
left: 10%
|
95
|
+
right: 10%
|
96
|
+
bottom: 20px
|
97
|
+
padding: 2px
|
98
|
+
background-color: #eee
|
99
|
+
text-align: center
|
100
|
+
font-size: 110%
|
101
|
+
a
|
102
|
+
font-weight: bold
|
103
|
+
|
@@ -0,0 +1,27 @@
|
|
1
|
+
@import "css3_prefix.sass"
|
2
|
+
|
3
|
+
!default_border_radius = 10px
|
4
|
+
|
5
|
+
=border-radius(!lt = "auto", !rt = "auto", !rb = "auto", !lb = "auto")
|
6
|
+
@if !lt == "auto"
|
7
|
+
!lt = !default_border_radius
|
8
|
+
@if !rt == "auto"
|
9
|
+
!rt = !lt
|
10
|
+
@if !rb == "auto"
|
11
|
+
!rb = !lt
|
12
|
+
@if !lb == "auto"
|
13
|
+
!lb = !rt
|
14
|
+
min-width = max(!lt + !rt, !lb + !rb)
|
15
|
+
min-height = max(!lt + !lb, !rt + !rb)
|
16
|
+
+border-radius-no-min-size(!lt, !rt, !rb, !lb)
|
17
|
+
|
18
|
+
=border-radius-no-min-size(!lt, !rt, !rb, !lb)
|
19
|
+
+prefixed("border-top-left-radius", !lt)
|
20
|
+
+prefixed("border-top-right-radius", !rt)
|
21
|
+
+prefixed("border-bottom-left-radius", !lb)
|
22
|
+
+prefixed("border-bottom-right-radius", !rb)
|
23
|
+
-moz-border-radius:
|
24
|
+
topleft = !lt
|
25
|
+
topright = !rt
|
26
|
+
bottomright = !rb
|
27
|
+
bottomleft = !lb
|
@@ -0,0 +1,14 @@
|
|
1
|
+
=prefixed(!attribute, !value)
|
2
|
+
-moz-#{!attribute} = !value
|
3
|
+
-webkit-#{!attribute} = !value
|
4
|
+
-khtml-#{!attribute} = !value
|
5
|
+
-ms-#{!attribute} = !value
|
6
|
+
-o-#{!attribute} = !value
|
7
|
+
#{!attribute} = !value
|
8
|
+
|
9
|
+
=box-shadow(!parameters)
|
10
|
+
+prefixed(box-shadow, !parameters)
|
11
|
+
|
12
|
+
=transition(!property, !duration)
|
13
|
+
+prefixed("transition-property", !property)
|
14
|
+
+prefixed("transition-duration", !duration)
|
@@ -0,0 +1,62 @@
|
|
1
|
+
@import border_radius.sass
|
2
|
+
@import css3_prefix.sass
|
3
|
+
|
4
|
+
!fancy_button_color = #222
|
5
|
+
!fancy_button_height = 30px
|
6
|
+
!fancy_button_width = "auto"
|
7
|
+
!fancy_button_radius = "auto"
|
8
|
+
!fancy_button_darkening = 0.3
|
9
|
+
|
10
|
+
=fancy-button(!color = !fancy_button_color, !height = !fancy_button_height, !width = !fancy_button_width, !radius = !fancy_button_radius)
|
11
|
+
@if !radius == "auto"
|
12
|
+
!radius = !height
|
13
|
+
@if !height < !radius * 2
|
14
|
+
!radius = !height / 2
|
15
|
+
+border-radius(!radius)
|
16
|
+
+box-shadow(0 1px 10px rgba(0, 0, 0, 0.6))
|
17
|
+
text-shadow = 0 -1px (!height * 0.1) rgba(0,0,0,0.7)
|
18
|
+
border-bottom: 1px solid rgba(0, 0, 0, 0.25)
|
19
|
+
background:
|
20
|
+
color = !color
|
21
|
+
image: url(/__big_band__/overlay-button.png)
|
22
|
+
repeat: repeat-x
|
23
|
+
attachment: scroll
|
24
|
+
position:
|
25
|
+
top: 0
|
26
|
+
left: 0
|
27
|
+
display: inline-block
|
28
|
+
padding = (!height * 0.1 - 1px) (!height * 0.5)
|
29
|
+
color: #fff !important
|
30
|
+
text:
|
31
|
+
decoration: none
|
32
|
+
align: center
|
33
|
+
-moz-background:
|
34
|
+
clip: border
|
35
|
+
inline-policy: continuous
|
36
|
+
font:
|
37
|
+
family: Arial,Helvetica,Helvetica Neue,Verdana,sans-serif
|
38
|
+
weight: bold
|
39
|
+
size = !height * 0.8
|
40
|
+
height = !height !important
|
41
|
+
width = !width
|
42
|
+
line-height: 1.2
|
43
|
+
|
44
|
+
=fancy-button-link(!color = !fancy_button_color, !height = !fancy_button_height, !width = !fancy_button_width, !radius = !fancy_button_radius, !darkening = !fancy_button_darkening)
|
45
|
+
!offset = !height * 0.1 + 3px
|
46
|
+
+fancy-button(!color, !height, !width, !radius)
|
47
|
+
+prefixed("transition-property", "background, left, top, box-shadow, -moz-box-shadow, -webkit-box-shadow")
|
48
|
+
+prefixed("transition-duration", "0.5s")
|
49
|
+
position: relative
|
50
|
+
top: 0
|
51
|
+
left: 0
|
52
|
+
cursor: pointer
|
53
|
+
margin = !offset
|
54
|
+
&:hover
|
55
|
+
+fancy-button(!color * !darkening, !height, !width, !radius)
|
56
|
+
+box-shadow(!offset !offset + 1px !offset + 10px rgba(0, 0, 0, 0.5))
|
57
|
+
left = -!offset
|
58
|
+
top = -!offset
|
59
|
+
&:visited, &:hover
|
60
|
+
color = !color
|
61
|
+
text-decoration: none
|
62
|
+
|
@@ -0,0 +1,94 @@
|
|
1
|
+
require "sinatra/base"
|
2
|
+
require "big_band/basic_extensions"
|
3
|
+
require "big_band/advanced_routes"
|
4
|
+
require "big_band/compass/big_band"
|
5
|
+
require "big_band/sass"
|
6
|
+
|
7
|
+
class BigBand < Sinatra::Base
|
8
|
+
|
9
|
+
# Integrates the Compass stylesheet framework with Sinatra.
|
10
|
+
#
|
11
|
+
# Usage without doing something:
|
12
|
+
#
|
13
|
+
# require "big_band"
|
14
|
+
# class Foo < BigBand; end
|
15
|
+
#
|
16
|
+
# If you create a directory called views/stylesheets and place your
|
17
|
+
# sass files in there, there you go. Just call stylesheet(name) form
|
18
|
+
# your view to get the correct stylesheet tag. The URL for your
|
19
|
+
# stylesheets will be /stylesheets/:name.css.
|
20
|
+
#
|
21
|
+
# Of course you can use any other setup. Say, you want to store your
|
22
|
+
# stylesheets in views/css and want the URL to be /css/:name.css:
|
23
|
+
#
|
24
|
+
# class Foo < BigBand
|
25
|
+
# get_compass("css")
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
# But what about more complex setups?
|
29
|
+
#
|
30
|
+
# class Foo < BigBand
|
31
|
+
# set :compass, :sass_dir => "/foo/bar/blah"
|
32
|
+
# get_compass("/foo/:name.css") do
|
33
|
+
# compass :one_stylesheet
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# Note that already generated routes will be deactivated by calling
|
38
|
+
# get_compass again.
|
39
|
+
module Compass
|
40
|
+
|
41
|
+
module ClassMethods
|
42
|
+
attr_reader :compass_route
|
43
|
+
def get_compass(path, &block)
|
44
|
+
block ||= Proc.new do |file|
|
45
|
+
content_type 'text/css', :charset => 'utf-8'
|
46
|
+
compass :"#{path}/#{params[:name]}"
|
47
|
+
end
|
48
|
+
set :compass, :sass_dir => klass.views / path unless compass[:sass_dir] && compass[:sass_dir].directory?
|
49
|
+
@compass_route.deactivate if @compass_route
|
50
|
+
@compass_route = get("/#{path}" / ":name.css", &block)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
module InstanceMethods
|
55
|
+
def compass(file, options = {})
|
56
|
+
options.merge! ::Compass.sass_engine_options
|
57
|
+
sass file, options
|
58
|
+
end
|
59
|
+
def stylesheet(*args)
|
60
|
+
raise NotImplementedError, "yet to be implemented"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def self.registered(klass)
|
65
|
+
klass.register BasicExtensions
|
66
|
+
klass.register AdvancedRoutes
|
67
|
+
klass.extend ClassMethods
|
68
|
+
klass.send :include, InstanceMethods
|
69
|
+
klass.set :compass,
|
70
|
+
:project_path => klass.root_path, :output_style => (klass.development? ? :expanded : :compressed),
|
71
|
+
:sass_dir => klass.views / "stylesheets", :line_comments => klass.development?
|
72
|
+
set_app_file(klass) if klass.app_file?
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.set_app_file(klass)
|
76
|
+
klass.set :compass, :root_path => klass.root_path
|
77
|
+
klass.get_compass("stylesheets") if (klass.views / "stylesheets").directory?
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.set_compass(klass)
|
81
|
+
::Compass.configuration do |config|
|
82
|
+
config.sass_options ||= {}
|
83
|
+
klass.compass.each do |option, value|
|
84
|
+
if config.respond_to? option
|
85
|
+
config.send "#{option}=", value
|
86
|
+
else
|
87
|
+
config.sass_options.merge! option.to_sym => value
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
end
|
Binary file
|