rack-reshow 0.1.0
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/.gitignore +21 -0
- data/LICENSE +20 -0
- data/README.textile +52 -0
- data/Rakefile +46 -0
- data/VERSION +1 -0
- data/lib/rack/__reshow__/action_back.gif +0 -0
- data/lib/rack/__reshow__/action_forward.gif +0 -0
- data/lib/rack/__reshow__/border.png +0 -0
- data/lib/rack/__reshow__/icon_alert.gif +0 -0
- data/lib/rack/__reshow__/reshow.css +44 -0
- data/lib/rack/__reshow__/reshow.js +107 -0
- data/lib/rack/reshow.rb +115 -0
- data/spec/reshow_spec.rb +69 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +10 -0
- metadata +90 -0
data/.gitignore
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2009 copypastel
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.textile
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
h1. rack-reshow
|
2
|
+
|
3
|
+
h2. the little toolbar that could
|
4
|
+
|
5
|
+
p. @Rack::Reshow@ adds a toolbar to rendered views that stores different versions of the page. Afterwards, reviewing and comparing outputted changes is a single click away.
|
6
|
+
|
7
|
+
h2. use
|
8
|
+
|
9
|
+
To install:
|
10
|
+
|
11
|
+
@gem install rack-reshow@
|
12
|
+
|
13
|
+
With Rails:
|
14
|
+
|
15
|
+
bq. config.gem "rack-reshow", :lib => "rack/reshow"
|
16
|
+
config.middleware.use "Rack::Reshow"
|
17
|
+
|
18
|
+
In your rackup file:
|
19
|
+
|
20
|
+
bq. require 'rack/reshow'
|
21
|
+
use Rack::Reshow
|
22
|
+
|
23
|
+
|
24
|
+
h2. why
|
25
|
+
|
26
|
+
p. Development of a view is a trial and error process by far: change code, reload the browser, change to previous version, reload the browser, compare the two versions, repeat until satisfied.
|
27
|
+
|
28
|
+
p. By storing the rendered views each time they change, @Rack::Reshow@ tightens the review loop, effectively creating a history for each page that can be clicked through.
|
29
|
+
|
30
|
+
h2. how
|
31
|
+
|
32
|
+
p. @Rack::Reshow@ uses @PStore@ to store different versions of a page.
|
33
|
+
|
34
|
+
p. Each time a request is received, @Rack::Reshow@ checks if the @<body>@ of the response differs from what it last was. If so, it adds it to the store. Afterwards, it injects all previous versions into the response, and makes them transversable via a small, elegant bar.
|
35
|
+
|
36
|
+
h2. limitations
|
37
|
+
|
38
|
+
p. @Rack::Reshow@ only works on responses that have a @<head>@ and @<body>@, namely the type of page one works with when dealing with a layout's look and feel.
|
39
|
+
|
40
|
+
p. Furthermore, it works best when javascript is applied unobtrusively; if there's any javascript inside the response's @<body>@, it'll get called once for each time said javascript code appears in the page's history.
|
41
|
+
|
42
|
+
p. Finally, the same page may have different content depending on session variables (i.e. after one logs in), or simply dynamic variables (i.e. displaying the date/time). @Rack::Reshow@ will store both versions separately, even though there's no code modification going on behind the scenes.
|
43
|
+
|
44
|
+
h2. thanks
|
45
|
+
|
46
|
+
p. "famfamfam":http://famfamfam.com for the elegant icons.
|
47
|
+
"Rack::Bug":http://github.com/brynary/rack-bug for insight into how to serve static content and inject content into a response.
|
48
|
+
"Jeweler":http://github.com/technicalpickles/jeweler for making publishing gems so simple.
|
49
|
+
|
50
|
+
h2. copyright
|
51
|
+
|
52
|
+
p. Copyright (c) 2010 copypastel. See LICENSE for details.
|
data/Rakefile
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "rack-reshow"
|
8
|
+
gem.summary = %Q{Time machine for your views in the shape of a Rack middleware.}
|
9
|
+
#gem.description = %Q{TODO: longer description of your gem}
|
10
|
+
gem.email = "ecin@copypastel.com"
|
11
|
+
gem.homepage = "http://github.com/ecin/rack-reshow"
|
12
|
+
gem.authors = ["ecin"]
|
13
|
+
gem.add_dependency "rack", ">= 1.0"
|
14
|
+
gem.add_development_dependency "rspec", ">= 1.2.9"
|
15
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
16
|
+
end
|
17
|
+
Jeweler::GemcutterTasks.new
|
18
|
+
rescue LoadError
|
19
|
+
puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
|
20
|
+
end
|
21
|
+
|
22
|
+
require 'spec/rake/spectask'
|
23
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
24
|
+
spec.libs << 'lib' << 'spec'
|
25
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
26
|
+
end
|
27
|
+
|
28
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
29
|
+
spec.libs << 'lib' << 'spec'
|
30
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
31
|
+
spec.rcov = true
|
32
|
+
end
|
33
|
+
|
34
|
+
task :spec => :check_dependencies
|
35
|
+
|
36
|
+
task :default => :spec
|
37
|
+
|
38
|
+
require 'rake/rdoctask'
|
39
|
+
Rake::RDocTask.new do |rdoc|
|
40
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
41
|
+
|
42
|
+
rdoc.rdoc_dir = 'rdoc'
|
43
|
+
rdoc.title = "rack-reshow #{version}"
|
44
|
+
rdoc.rdoc_files.include('README*')
|
45
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
46
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -0,0 +1,44 @@
|
|
1
|
+
#__reshow_bar__{
|
2
|
+
padding: 3px 15px 3px 15px;
|
3
|
+
margin: 0;
|
4
|
+
font-family: helvetica;
|
5
|
+
text-align: center;
|
6
|
+
position: fixed;
|
7
|
+
top: -25px;
|
8
|
+
left: 50px;
|
9
|
+
height: 25px;
|
10
|
+
background: url(/__reshow__/border.png) white repeat-x bottom left;
|
11
|
+
border-left: 1px solid #ccc;
|
12
|
+
border-right: 1px solid #ccc;
|
13
|
+
z-index: 1024;
|
14
|
+
}
|
15
|
+
|
16
|
+
#__reshow_bar__ img{
|
17
|
+
cursor: pointer;
|
18
|
+
position: relative;
|
19
|
+
top: 3px;
|
20
|
+
}
|
21
|
+
|
22
|
+
#__reshow_version__{
|
23
|
+
font-weight: bold;
|
24
|
+
margin-right: 10px;
|
25
|
+
color: steelblue;
|
26
|
+
}
|
27
|
+
|
28
|
+
#__reshow_info__{
|
29
|
+
opacity: 0.33;
|
30
|
+
}
|
31
|
+
|
32
|
+
#__reshow_next__{
|
33
|
+
opacity: 0.33;
|
34
|
+
}
|
35
|
+
|
36
|
+
.__reshow_body__{
|
37
|
+
opacity: 0;
|
38
|
+
display: none;
|
39
|
+
}
|
40
|
+
|
41
|
+
.__reshow_active__{
|
42
|
+
opacity: 1;
|
43
|
+
display: block;
|
44
|
+
}
|
@@ -0,0 +1,107 @@
|
|
1
|
+
jQuery(document).ready( function(){
|
2
|
+
|
3
|
+
jQuery.extend( jQuery.easing, {
|
4
|
+
'easeOutBounce': function(x, t, b, c, d) {
|
5
|
+
if ((t/=d) < (1/2.75)) {
|
6
|
+
return c*(7.5625*t*t) + b;
|
7
|
+
} else if (t < (2/2.75)) {
|
8
|
+
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
|
9
|
+
} else if (t < (2.5/2.75)) {
|
10
|
+
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
|
11
|
+
} else {
|
12
|
+
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
|
13
|
+
}
|
14
|
+
}
|
15
|
+
});
|
16
|
+
|
17
|
+
var __reshow__ = {
|
18
|
+
prev: function(){
|
19
|
+
var active = jQuery('.__reshow_active__');
|
20
|
+
var el = jQuery(this);
|
21
|
+
if(active.prev().length > 0){
|
22
|
+
active.animate({opacity: 0},
|
23
|
+
{
|
24
|
+
complete: function(){
|
25
|
+
active.css('display', 'none');
|
26
|
+
active.toggleClass('__reshow_active__')
|
27
|
+
active = active.prev('.__reshow_body__');
|
28
|
+
active.toggleClass( '__reshow_active__')
|
29
|
+
active.css('opacity', 0);
|
30
|
+
active.css('display', 'block');
|
31
|
+
active.animate({opacity: 1});
|
32
|
+
var version = Number(jQuery('#__reshow_version__').text()) - 1;
|
33
|
+
version = (version < 10 ? '0' : '') + version
|
34
|
+
jQuery('#__reshow_version__').text(version);
|
35
|
+
// Okay, bind the click again.
|
36
|
+
el.one('click', __reshow__.prev);
|
37
|
+
if(active.prev().length > 0){
|
38
|
+
// Okay, bind the click again.
|
39
|
+
el.one('click', __reshow__.prev);
|
40
|
+
} else{
|
41
|
+
el.animate({opacity: 0.33});
|
42
|
+
}
|
43
|
+
jQuery('#__reshow_next__').animate({opacity: 1}).one('click', __reshow__.next);
|
44
|
+
}
|
45
|
+
});
|
46
|
+
} else{
|
47
|
+
el.one('click', __reshow__.prev);
|
48
|
+
}
|
49
|
+
},
|
50
|
+
next: function(){
|
51
|
+
var active = jQuery('.__reshow_active__');
|
52
|
+
var el = jQuery(this);
|
53
|
+
if(active.next().length > 0){
|
54
|
+
active.animate({opacity: 0},
|
55
|
+
{
|
56
|
+
complete: function(){
|
57
|
+
active.css('display', 'none');
|
58
|
+
active.toggleClass('__reshow_active__')
|
59
|
+
active = active.next()
|
60
|
+
active.toggleClass( '__reshow_active__')
|
61
|
+
active.css('opacity', 0);
|
62
|
+
active.css('display', 'block');
|
63
|
+
active.animate({opacity: 1});
|
64
|
+
var version = Number(jQuery('#__reshow_version__').text()) + 1;
|
65
|
+
version = (version < 10 ? '0' : '') + version
|
66
|
+
jQuery('#__reshow_version__').text(version);
|
67
|
+
if(active.next().length > 0){
|
68
|
+
// Okay, bind the click again.
|
69
|
+
el.one('click', __reshow__.next);
|
70
|
+
} else{
|
71
|
+
el.animate({opacity: 0.33});
|
72
|
+
}
|
73
|
+
jQuery('#__reshow_prev__').animate({opacity: 1}).one('click', __reshow__.prev);
|
74
|
+
}
|
75
|
+
});
|
76
|
+
} else{
|
77
|
+
el.one('click', __reshow__.next);
|
78
|
+
}
|
79
|
+
}
|
80
|
+
};
|
81
|
+
|
82
|
+
jQuery('.__reshow_body__:last').toggleClass('__reshow_active__');
|
83
|
+
if(jQuery('.__reshow_active__').prev().length > 0)
|
84
|
+
jQuery('#__reshow_prev__').one('click', __reshow__.prev);
|
85
|
+
//jQuery('#__reshow_next__').one('click', __reshow__.next);
|
86
|
+
jQuery('#__reshow_info__').click( function(){
|
87
|
+
console.log("To be replaced with a Swift.js tooltip.");
|
88
|
+
});
|
89
|
+
|
90
|
+
var bar = jQuery('#__reshow_bar__');
|
91
|
+
|
92
|
+
setTimeout(function(){
|
93
|
+
bar.animate({'top': 0}, 'slow', 'easeOutBounce').animate({'opacity': 0.3},
|
94
|
+
{
|
95
|
+
complete: function(){
|
96
|
+
bar.bind('mouseover', function(){
|
97
|
+
jQuery(this).stop().animate({'opacity': 1});
|
98
|
+
});
|
99
|
+
|
100
|
+
bar.bind('mouseout', function(){
|
101
|
+
jQuery(this).stop().animate({'opacity': 0.3});
|
102
|
+
});
|
103
|
+
}
|
104
|
+
});
|
105
|
+
}, 1000);
|
106
|
+
|
107
|
+
});
|
data/lib/rack/reshow.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
require 'pstore'
|
2
|
+
require 'rack/static'
|
3
|
+
|
4
|
+
module Rack
|
5
|
+
class Reshow
|
6
|
+
|
7
|
+
class RackStaticBugAvoider
|
8
|
+
def initialize(app, static_app)
|
9
|
+
@app = app
|
10
|
+
@static_app = static_app
|
11
|
+
end
|
12
|
+
|
13
|
+
def call(env)
|
14
|
+
if env["PATH_INFO"]
|
15
|
+
@static_app.call(env)
|
16
|
+
else
|
17
|
+
@app.call(env)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
@@store_file = 'reshow.ps'
|
23
|
+
|
24
|
+
def initialize( app, opts = {} )
|
25
|
+
root = Object::File.expand_path(Object::File.dirname(__FILE__))
|
26
|
+
@app = RackStaticBugAvoider.new(app, Rack::Static.new(app, :urls => ["/__reshow__"], :root => root))
|
27
|
+
@store = PStore.new(@@store_file)
|
28
|
+
end
|
29
|
+
|
30
|
+
def call( env )
|
31
|
+
status, headers, body = @app.call(env)
|
32
|
+
request = Request.new(env)
|
33
|
+
if request.get? and status == 200
|
34
|
+
path = request.path
|
35
|
+
if body.respond_to? :join
|
36
|
+
body = body.join
|
37
|
+
@store.transaction do |store|
|
38
|
+
store[path] ||= []
|
39
|
+
content = body.scan(/<body>(.*?)<\/body>/m).flatten.first
|
40
|
+
store[path] << content unless content.nil? or store[path].last.eql?(content)
|
41
|
+
body.sub! /<body>.*<\/body>/m, %q{<body><div id="__reshow_bodies__"></div></body>}
|
42
|
+
store[path].reverse.each do |c|
|
43
|
+
prepend_to_tag '<div id="__reshow_bodies__">', body, tag(:div, c, :class => '__reshow_body__')
|
44
|
+
end
|
45
|
+
insert_reshow_bar body, store[path].size
|
46
|
+
end
|
47
|
+
headers['Content-Length'] = body.length.to_s
|
48
|
+
body = [body]
|
49
|
+
end
|
50
|
+
end
|
51
|
+
[status, headers, body]
|
52
|
+
end
|
53
|
+
|
54
|
+
def []( path )
|
55
|
+
@store.transaction(true) {|store| store[path] || Array.new}
|
56
|
+
end
|
57
|
+
|
58
|
+
def purge!
|
59
|
+
Object::File.delete(@@store_file) if Object::File.exists?(@@store_file)
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def prepend_to_tag(tag, page, string)
|
65
|
+
page.sub! /#{tag}/, "#{tag}\n" + string
|
66
|
+
end
|
67
|
+
|
68
|
+
def append_to_tag(tag, page, string)
|
69
|
+
page.sub! /#{tag}/, string + "\n#{tag}"
|
70
|
+
end
|
71
|
+
|
72
|
+
def insert_reshow_bar(page, versions)
|
73
|
+
append_to_tag '</head>', page, style
|
74
|
+
append_to_tag '</head>', page, jquery
|
75
|
+
append_to_tag '</head>', page, javascript
|
76
|
+
append_to_tag '</body>', page, toolbar(versions)
|
77
|
+
end
|
78
|
+
|
79
|
+
def tag(type, body, options={})
|
80
|
+
options = options.map {|key, value| "#{key}=\"#{value}\""}.join(' ')
|
81
|
+
<<-EOF
|
82
|
+
<#{type} #{options}">
|
83
|
+
#{body}
|
84
|
+
</#{type}>
|
85
|
+
EOF
|
86
|
+
end
|
87
|
+
|
88
|
+
def toolbar(versions)
|
89
|
+
versions = (versions < 10 ? '0' : '') + versions.to_s
|
90
|
+
<<-EOF
|
91
|
+
<div id="__reshow_bar__">
|
92
|
+
<span id="__reshow_version__">#{versions}</span>
|
93
|
+
<span style="margin-right: 10px;">
|
94
|
+
<img id="__reshow_prev__" src="/__reshow__/action_back.gif" style="margin-right: 7px;"/>
|
95
|
+
<img id="__reshow_next__" src="/__reshow__/action_forward.gif" />
|
96
|
+
</span>
|
97
|
+
<span><img id="__reshow_info__" src="/__reshow__/icon_alert.gif" /></span>
|
98
|
+
</div>
|
99
|
+
EOF
|
100
|
+
end
|
101
|
+
|
102
|
+
def style
|
103
|
+
%q{<link charset='utf-8' href="/__reshow__/reshow.css" rel='stylesheet' type='text/css'>}
|
104
|
+
end
|
105
|
+
|
106
|
+
def javascript
|
107
|
+
%q{<script src="/__reshow__/reshow.js"></script>}
|
108
|
+
end
|
109
|
+
|
110
|
+
def jquery
|
111
|
+
%q{<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>}
|
112
|
+
end
|
113
|
+
|
114
|
+
end
|
115
|
+
end
|
data/spec/reshow_spec.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
include Rack
|
4
|
+
|
5
|
+
# Need to change the app for some test cases
|
6
|
+
class Rack::Reshow; attr_accessor :app; end
|
7
|
+
|
8
|
+
describe Rack::Reshow do
|
9
|
+
|
10
|
+
# Set up configuration variables
|
11
|
+
|
12
|
+
before :all do
|
13
|
+
@post_url = '/comments'
|
14
|
+
@env = Rack::MockRequest.env_for '/'
|
15
|
+
# The Lambdacat App
|
16
|
+
@body = ["<body>Lambda, lambda, lambda app, hoooo!</body>"]
|
17
|
+
@body2 = ["<body>Lambda app is on the run, lambda app is loose!</body>"]
|
18
|
+
@app = lambda {|env| [200, {}, @body]}
|
19
|
+
end
|
20
|
+
|
21
|
+
# Rack::Reshow middleware can be instantiated
|
22
|
+
it 'should accept an :app and an :opts hash at instantiation' do
|
23
|
+
lambda { Reshow.new(@app, {}) }.should_not raise_error
|
24
|
+
end
|
25
|
+
|
26
|
+
before(:each) { @middleware = Reshow.new @app }
|
27
|
+
|
28
|
+
it 'should return an array with stored versions given a path' do
|
29
|
+
@middleware['/'].should be_empty
|
30
|
+
@middleware.call @env
|
31
|
+
@middleware['/'].size.should == 1
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should allow to purge the pstore' do
|
35
|
+
@middleware.call @env
|
36
|
+
@middleware['/'].should_not be_empty
|
37
|
+
@middleware.purge!
|
38
|
+
@middleware['/'].should be_empty
|
39
|
+
end
|
40
|
+
|
41
|
+
after(:each) { @middleware.purge! }
|
42
|
+
|
43
|
+
# Rack::Reshow#call is defined, as in any middleware
|
44
|
+
it 'should return an array with status, headers, and body when sent :call' do
|
45
|
+
response = @middleware.call @env
|
46
|
+
response.class.should be(Array)
|
47
|
+
response.size.should == 3
|
48
|
+
response[2] == @body.to_s.scan(/<body>(.*?)<\/body>/m).flatten.first
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should save a version of a page when the content changes' do
|
52
|
+
@middleware.call @env
|
53
|
+
@middleware.app = lambda {|env| [200, {}, @body2]}
|
54
|
+
@middleware.call @env
|
55
|
+
@middleware['/'].size.should == 2
|
56
|
+
versions = @middleware['/']
|
57
|
+
versions[0].should match("Lambda, lambda, lambda app, hoooo!")
|
58
|
+
versions[1].should match("Lambda app is on the run, lambda app is loose!")
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should return all bodies in history (though hidden by css)' do
|
62
|
+
@middleware.call @env
|
63
|
+
@middleware.app = lambda {|env| [200, {}, @body2]}
|
64
|
+
status, headers, body = @middleware.call @env
|
65
|
+
body.to_s.should match(/Lambda app is on the run, lambda app is loose!/)
|
66
|
+
body.to_s.should match(/Lambda, lambda, lambda app, hoooo!/)
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-reshow
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- ecin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-01-07 00:00:00 -04:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: rack
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "1.0"
|
24
|
+
version:
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
type: :development
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.2.9
|
34
|
+
version:
|
35
|
+
description:
|
36
|
+
email: ecin@copypastel.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files:
|
42
|
+
- LICENSE
|
43
|
+
- README.textile
|
44
|
+
files:
|
45
|
+
- .gitignore
|
46
|
+
- LICENSE
|
47
|
+
- README.textile
|
48
|
+
- Rakefile
|
49
|
+
- VERSION
|
50
|
+
- lib/rack/__reshow__/action_back.gif
|
51
|
+
- lib/rack/__reshow__/action_forward.gif
|
52
|
+
- lib/rack/__reshow__/border.png
|
53
|
+
- lib/rack/__reshow__/icon_alert.gif
|
54
|
+
- lib/rack/__reshow__/reshow.css
|
55
|
+
- lib/rack/__reshow__/reshow.js
|
56
|
+
- lib/rack/reshow.rb
|
57
|
+
- spec/reshow_spec.rb
|
58
|
+
- spec/spec.opts
|
59
|
+
- spec/spec_helper.rb
|
60
|
+
has_rdoc: true
|
61
|
+
homepage: http://github.com/ecin/rack-reshow
|
62
|
+
licenses: []
|
63
|
+
|
64
|
+
post_install_message:
|
65
|
+
rdoc_options:
|
66
|
+
- --charset=UTF-8
|
67
|
+
require_paths:
|
68
|
+
- lib
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: "0"
|
74
|
+
version:
|
75
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ">="
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: "0"
|
80
|
+
version:
|
81
|
+
requirements: []
|
82
|
+
|
83
|
+
rubyforge_project:
|
84
|
+
rubygems_version: 1.3.5
|
85
|
+
signing_key:
|
86
|
+
specification_version: 3
|
87
|
+
summary: Time machine for your views in the shape of a Rack middleware.
|
88
|
+
test_files:
|
89
|
+
- spec/reshow_spec.rb
|
90
|
+
- spec/spec_helper.rb
|