rack-reshow 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -16,12 +16,18 @@ jQuery(document).ready( function(){
16
16
 
17
17
  var __reshow__ = {
18
18
  prev: function(){
19
- var active = jQuery('.__reshow_active__');
19
+ var active = jQuery('div.__reshow_active__');
20
20
  var el = jQuery(this);
21
+ var css = jQuery('link.__reshow_active__');
21
22
  if(active.prev().length > 0){
22
23
  active.animate({opacity: 0},
23
24
  {
24
25
  complete: function(){
26
+ css.toggleClass('__reshow_active__');
27
+ css[0].disabled = true;
28
+ css = css.prev();
29
+ css.toggleClass('__reshow_active__');
30
+ css[0].disabled = false;
25
31
  active.css('display', 'none');
26
32
  active.toggleClass('__reshow_active__')
27
33
  active = active.prev('.__reshow_body__');
@@ -33,7 +39,6 @@ jQuery(document).ready( function(){
33
39
  version = (version < 10 ? '0' : '') + version
34
40
  jQuery('#__reshow_version__').text(version);
35
41
  // Okay, bind the click again.
36
- el.one('click', __reshow__.prev);
37
42
  if(active.prev().length > 0){
38
43
  // Okay, bind the click again.
39
44
  el.one('click', __reshow__.prev);
@@ -48,12 +53,18 @@ jQuery(document).ready( function(){
48
53
  }
49
54
  },
50
55
  next: function(){
51
- var active = jQuery('.__reshow_active__');
56
+ var active = jQuery('div.__reshow_active__');
52
57
  var el = jQuery(this);
58
+ var css = jQuery('link.__reshow_active__');
53
59
  if(active.next().length > 0){
54
60
  active.animate({opacity: 0},
55
61
  {
56
62
  complete: function(){
63
+ css.toggleClass('__reshow_active__');
64
+ css[0].disabled = true;
65
+ css = css.next();
66
+ css.toggleClass('__reshow_active__');
67
+ css[0].disabled = false;
57
68
  active.css('display', 'none');
58
69
  active.toggleClass('__reshow_active__')
59
70
  active = active.next()
@@ -79,14 +90,34 @@ jQuery(document).ready( function(){
79
90
  }
80
91
  };
81
92
 
93
+ // Disable all stylesheets except for reshow.css
94
+
95
+ jQuery('link[rel*=style]').each( function(){
96
+ if(jQuery(this).attr('href') != '/__reshow__/reshow.css')
97
+ this.disabled = true;
98
+ });
99
+
100
+ // Enable most recent stylesheet
101
+
102
+ jQuery('link[rel*=style]:last').each( function(){
103
+ this.disabled = false;
104
+ jQuery(this).toggleClass('__reshow_active__');
105
+ });
106
+
107
+ // Bind initial clicks
108
+
82
109
  jQuery('.__reshow_body__:last').toggleClass('__reshow_active__');
83
- if(jQuery('.__reshow_active__').prev().length > 0)
110
+ if(jQuery('div.__reshow_active__').prev().length > 0)
84
111
  jQuery('#__reshow_prev__').one('click', __reshow__.prev);
112
+ else
113
+ jQuery('#__reshow_prev__').css({opacity: 0.33});
85
114
  //jQuery('#__reshow_next__').one('click', __reshow__.next);
86
115
  jQuery('#__reshow_info__').click( function(){
87
116
  console.log("To be replaced with a Swift.js tooltip.");
88
117
  });
89
118
 
119
+ // Bar animation
120
+
90
121
  var bar = jQuery('#__reshow_bar__');
91
122
 
92
123
  setTimeout(function(){
@@ -1,8 +1,90 @@
1
1
  require 'pstore'
2
2
  require 'rack/static'
3
+ require 'open-uri'
3
4
 
4
5
  module Rack
5
6
  class Reshow
7
+
8
+ class Page
9
+
10
+ class << self
11
+ def tag(type, content, options={})
12
+ options = options.map {|key, value| "#{key}=\"#{value}\""}.join(' ')
13
+ <<-EOF
14
+ <#{type} #{options}">
15
+ #{content}
16
+ </#{type}>
17
+ EOF
18
+ end
19
+ end
20
+
21
+ def initialize(html, path, app)
22
+ @html = html
23
+ @path = path
24
+ self.stylesheets!(app)
25
+ end
26
+
27
+ def to_s
28
+ @html
29
+ end
30
+
31
+ def head
32
+ @html.scan(/<head>(.*?)<\/head>/m).flatten.first
33
+ end
34
+
35
+ def head=(content)
36
+ @html.sub! /<head>.*<\/head>/m, "<head>#{content}</head>"
37
+ end
38
+
39
+ def body
40
+ @html.scan(/<body>(.*?)<\/body>/m).flatten.first
41
+ end
42
+
43
+ def body=(content)
44
+ @html.sub! /<body>.*<\/body>/m, "<body>#{content}</body>"
45
+ end
46
+
47
+ def stylesheets
48
+ @stylesheets.each_value.to_a.join
49
+ end
50
+
51
+ def stylesheets!(app)
52
+ @stylesheets ||= begin
53
+ @stylesheets = {}
54
+ links = head.scan(/<link.*?rel=['|"]+stylesheet['|"]+.*?>/)
55
+ links.each do |link|
56
+ href = link.scan(/href=['|"]+(.*?)['|"]+/).flatten.first
57
+ if href[/https?:\/\//]
58
+ @stylesheets[href] = open(href).read
59
+ else
60
+ href = @path + href unless href[0] == ?/
61
+ status, headers, body = app.call Rack::MockRequest.env_for(href)
62
+ sheet = ''
63
+ body.each {|part| sheet << part}
64
+ @stylesheets[href] = sheet
65
+ end
66
+ end
67
+ @stylesheets
68
+ end
69
+ end
70
+
71
+ def length
72
+ @html.length
73
+ end
74
+
75
+ def eql?(page)
76
+ body == page.body and stylesheets == page.stylesheets
77
+ end
78
+
79
+ def prepend_to_tag(tag, string)
80
+ @html.sub! /#{tag}/, "#{tag}\n" + string
81
+ end
82
+
83
+ def append_to_tag(tag, string)
84
+ @html.sub! /#{tag}/, string + "\n#{tag}"
85
+ end
86
+
87
+ end
6
88
 
7
89
  class RackStaticBugAvoider
8
90
  def initialize(app, static_app)
@@ -28,25 +110,38 @@ module Rack
28
110
  end
29
111
 
30
112
  def call( env )
31
- status, headers, body = @app.call(env)
32
113
  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
114
+ path = request.path
115
+ return serve_stylesheet(request) if path =~ /__reshow__\/assets/
116
+ status, headers, body = @app.call(env)
117
+ if status == 200 and body.respond_to? :join
118
+ body = body.join
119
+ page = Page.new body, path, @app
120
+ # Store response
121
+ @store.transaction do |store|
122
+ store[path] ||= []
123
+ store[path] << page unless body.nil? or store[path].last.eql?(page)
124
+ end
125
+ # Insert Reshow assets
126
+ page.append_to_tag '</head>', [style, javascript].join("\n")
127
+ # Prepare for Reshow bar
128
+ @store.transaction(true) do |store|
129
+ page.body = %q{<div id="__reshow_bodies__"></div>}
130
+ store[path].reverse.each do |p|
131
+ page.prepend_to_tag '<div id="__reshow_bodies__">', Page.tag(:div, p.body, :class => '__reshow_body__')
132
+ end
133
+ versions = store[path].count
134
+ # Insert Reshow Bar
135
+ page.append_to_tag '</body>', toolbar(versions)
136
+ # Insert versioned stylesheets
137
+ versions.times do |v|
138
+ escaped_path = Rack::Utils.escape(path)
139
+ href = "/__reshow__/assets?path=#{escaped_path}&version=#{v}"
140
+ page.append_to_tag '</head>', "<link charset='utf-8' href='#{href}' rel='stylesheet' type='text/css'>"
46
141
  end
47
- headers['Content-Length'] = body.length.to_s
48
- body = [body]
49
142
  end
143
+ headers['Content-Length'] = page.length
144
+ body = [page.to_s]
50
145
  end
51
146
  [status, headers, body]
52
147
  end
@@ -61,28 +156,13 @@ module Rack
61
156
 
62
157
  private
63
158
 
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
159
+ def serve_stylesheet(request)
160
+ version = request.params['version'].to_i
161
+ stylesheets = ''
162
+ @store.transaction(true) do |store|
163
+ stylesheets = store[request.params['path']][version].stylesheets
164
+ end
165
+ [200, {'Content-Length' => stylesheets.length.to_s, 'Content-Type' => 'text/css'}, [stylesheets]]
86
166
  end
87
167
 
88
168
  def toolbar(versions)
@@ -104,12 +184,10 @@ module Rack
104
184
  end
105
185
 
106
186
  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>}
187
+ <<-EOF
188
+ <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script>
189
+ <script src="/__reshow__/reshow.js"></script>
190
+ EOF
112
191
  end
113
-
114
192
  end
115
193
  end
@@ -0,0 +1,143 @@
1
+ *{
2
+ padding: 0;
3
+ margin: 0;
4
+ font-family: helvetica, arial, sans-serif;
5
+ color: #111;
6
+ }
7
+
8
+ body{
9
+ min-height: 100%;
10
+ min-width: 800px;
11
+ }
12
+
13
+ a{
14
+ text-decoration: none;
15
+ }
16
+
17
+ a:hover{
18
+ color: #027dff;
19
+ }
20
+
21
+ a:visited{
22
+ text-decoration: line-through;
23
+ }
24
+
25
+ img{
26
+ border: 0;
27
+ }
28
+
29
+ #logo{
30
+ background: url(/img/logo.png);
31
+ height: 94px;
32
+ width: 411px;
33
+ position: fixed;
34
+ bottom: 0;
35
+ left: 0;
36
+ margin: 0 0 40px 20px;
37
+ }
38
+
39
+ #logo:hover{
40
+ background: url(/img/logo_color.png);
41
+ }
42
+
43
+ #are{
44
+ float: left;
45
+ width: 449px;
46
+ }
47
+
48
+ .is{
49
+ float: left;
50
+ width: 200px;
51
+ padding: 20px 0px 0 20px;
52
+ cursor: pointer;
53
+ }
54
+
55
+ .who{
56
+ font-weight: bold;
57
+ font-size: 25px;
58
+ color: #ccc;
59
+ }
60
+
61
+ .name{
62
+ display: inline;
63
+ color: #ccc;
64
+ }
65
+
66
+ .what{
67
+ font-size: 20px;
68
+ color: #ddd;
69
+ }
70
+
71
+ .is:hover .name{
72
+ color: #8fd92a;
73
+ }
74
+
75
+ .is:hover .what{
76
+ color: #111;
77
+ }
78
+
79
+ .bacon{
80
+ position: absolute;
81
+ top: 110px;
82
+ }
83
+
84
+ .twitter{
85
+ height: 82px;
86
+ width: 100px;
87
+ background: url(/img/twitter.png);
88
+ }
89
+
90
+ .twitter:hover{
91
+ background: url(/img/twitter_color.png);
92
+ }
93
+
94
+ .github{
95
+ height: 60px;
96
+ width: 123px;
97
+ background: url(/img/github.png);
98
+ opacity: 0.5;
99
+ }
100
+
101
+ .github:hover{
102
+ opacity: 1;
103
+ }
104
+
105
+ .flickr{
106
+ height: 35px;
107
+ width: 130px;
108
+ background: url(/img/flickr.png);
109
+ }
110
+
111
+ .flickr:hover{
112
+ background: url(/img/flickr_color.png);
113
+ }
114
+
115
+ #rofls{
116
+ margin-left: 449px;
117
+ }
118
+
119
+ .rofl{
120
+ cursor: pointer;
121
+ position: relative;
122
+ padding: 5px 0 5px 10px;
123
+ border-left: 10px solid #fafafa;
124
+ }
125
+
126
+ .rofl:nth-child(even){
127
+ background: #fafafa;
128
+ }
129
+
130
+ .rofl_title{
131
+ font-size: 32px;
132
+ font-weight: bold;
133
+ }
134
+
135
+ .rofl:hover .rofl_date{
136
+ color: #027dff;
137
+ }
138
+
139
+ .rofl_date{
140
+ color: #ccc;
141
+ font-size: 32px;
142
+ display: inline;
143
+ }
@@ -0,0 +1,73 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Blog.new :copypastel</title>
5
+ <link charset='utf-8' href='/public/v1.css' rel='stylesheet' type='text/css'>
6
+ <link href='rofls.rss' rel='alternate' title='copypastel' type='application/rss+xml'>
7
+ <meta charset='utf-8' content='text/html' http-equiv='Content-Type'>
8
+ </head>
9
+ <body>
10
+ <a href='http://copypastel.com'>
11
+ <div id='logo'></div>
12
+ </a>
13
+ <div id='are'>
14
+ <div class='is'>
15
+ <div class='who'>
16
+ <div class='name'>ecin</div>
17
+ is...
18
+ </div>
19
+ <div class='what'>working for 2 weeks as work-for-hire.</div>
20
+ <div class='bacon'>
21
+ <a href='http://twitter.com/ecin'>
22
+ <div class='twitter'></div>
23
+ </a>
24
+ <a href='http://flickr.com/photos/ecin'>
25
+ <div class='flickr'></div>
26
+ </a>
27
+ <a href='http://github.com/ecin'>
28
+ <div class='github'></div>
29
+ </a>
30
+ </div>
31
+ </div>
32
+ <div class='is'>
33
+ <div class='who'>
34
+ <div class='name'>daicoden</div>
35
+ is...
36
+ </div>
37
+ <div class='what'>building a startup.</div>
38
+ <div class='bacon'>
39
+ <a href='http://twitter.com/daicoden'>
40
+ <div class='twitter'></div>
41
+ </a>
42
+ <a href='http://flickr.com/photos/daicoden'>
43
+ <div class='flickr'></div>
44
+ </a>
45
+ <a href='http://github.com/daicoden'>
46
+ <div class='github'></div>
47
+ </a>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <div id='rofls'>
52
+ <a href='/rofl/Singletasking'>
53
+ <div class='rofl'>
54
+ <div class='rofl_title'>
55
+ <div class='rofl_date'>16.09.09</div>
56
+ Singletasking
57
+ </div>
58
+ </div>
59
+ </a>
60
+ <a href='/rofl/Rehashing_Hashapass'>
61
+ <div class='rofl'>
62
+ <div class='rofl_title'>
63
+ <div class='rofl_date'>29.09.09</div>
64
+ Rehashing Hashapass
65
+ </div>
66
+ </div>
67
+ </a>
68
+ </div>
69
+ <img src='/img/logo_color.png' style='display: none;'>
70
+ <img src='/img/flickr_color.png' style='display: none;'>
71
+ <img src='/img/twitter_color.png' style='display: none;'>
72
+ </body>
73
+ </html>
@@ -0,0 +1,3 @@
1
+ *{
2
+ background: black;
3
+ }
@@ -0,0 +1,73 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Blog.new :copypastel</title>
5
+ <link charset='utf-8' href='/public/v2.css' rel='stylesheet' type='text/css'>
6
+ <link href='rofls.rss' rel='alternate' title='copypastel' type='application/rss+xml'>
7
+ <meta charset='utf-8' content='text/html' http-equiv='Content-Type'>
8
+ </head>
9
+ <body>
10
+ <a href='http://copypastel.com'>
11
+ <div id='logo'></div>
12
+ </a>
13
+ <div id='are'>
14
+ <div class='is'>
15
+ <div class='who'>
16
+ <div class='name'>ecin</div>
17
+ is...
18
+ </div>
19
+ <div class='what'>testing Rack::Reshow.</div>
20
+ <div class='bacon'>
21
+ <a href='http://twitter.com/ecin'>
22
+ <div class='twitter'></div>
23
+ </a>
24
+ <a href='http://flickr.com/photos/ecin'>
25
+ <div class='flickr'></div>
26
+ </a>
27
+ <a href='http://github.com/ecin'>
28
+ <div class='github'></div>
29
+ </a>
30
+ </div>
31
+ </div>
32
+ <div class='is'>
33
+ <div class='who'>
34
+ <div class='name'>daicoden</div>
35
+ is...
36
+ </div>
37
+ <div class='what'>building a startup.</div>
38
+ <div class='bacon'>
39
+ <a href='http://twitter.com/daicoden'>
40
+ <div class='twitter'></div>
41
+ </a>
42
+ <a href='http://flickr.com/photos/daicoden'>
43
+ <div class='flickr'></div>
44
+ </a>
45
+ <a href='http://github.com/daicoden'>
46
+ <div class='github'></div>
47
+ </a>
48
+ </div>
49
+ </div>
50
+ </div>
51
+ <div id='rofls'>
52
+ <a href='/rofl/Singletasking'>
53
+ <div class='rofl'>
54
+ <div class='rofl_title'>
55
+ <div class='rofl_date'>16.09.09</div>
56
+ Singletasking
57
+ </div>
58
+ </div>
59
+ </a>
60
+ <a href='/rofl/Rehashing_Hashapass'>
61
+ <div class='rofl'>
62
+ <div class='rofl_title'>
63
+ <div class='rofl_date'>29.09.09</div>
64
+ Rehashing Hashapass
65
+ </div>
66
+ </div>
67
+ </a>
68
+ </div>
69
+ <img src='/img/logo_color.png' style='display: none;'>
70
+ <img src='/img/flickr_color.png' style='display: none;'>
71
+ <img src='/img/twitter_color.png' style='display: none;'>
72
+ </body>
73
+ </html>
@@ -6,16 +6,18 @@ include Rack
6
6
  class Rack::Reshow; attr_accessor :app; end
7
7
 
8
8
  describe Rack::Reshow do
9
+ include Rack::Test::Methods
9
10
 
10
- # Set up configuration variables
11
-
11
+ # Set up configuration
12
12
  before :all do
13
- @post_url = '/comments'
13
+ @root = Object::File.expand_path(Object::File.dirname(__FILE__))
14
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]}
15
+ @body = [File.open(@root + '/public/v1.html').read]
16
+ @body2 = [File.open(@root + '/public/v2.html').read]
17
+ @css = File.open(@root + '/public/v1.css').read
18
+ @css2 = File.open(@root + '/public/v2.css').read
19
+ app = lambda {|env| [200, {}, @body]}
20
+ @app = Rack::Static.new(app, :urls => ["/public"], :root => @root)
19
21
  end
20
22
 
21
23
  # Rack::Reshow middleware can be instantiated
@@ -45,7 +47,7 @@ describe Rack::Reshow do
45
47
  response = @middleware.call @env
46
48
  response.class.should be(Array)
47
49
  response.size.should == 3
48
- response[2] == @body.to_s.scan(/<body>(.*?)<\/body>/m).flatten.first
50
+ response.last.should respond_to(:each)
49
51
  end
50
52
 
51
53
  it 'should save a version of a page when the content changes' do
@@ -54,16 +56,46 @@ describe Rack::Reshow do
54
56
  @middleware.call @env
55
57
  @middleware['/'].size.should == 2
56
58
  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
+ versions[0].body.should match(/#{@body.to_s.scan(/<body>(.*?)<\/body>/m).flatten.first}/)
60
+ versions[1].body.should match(/#{@body2.to_s.scan(/<body>(.*?)<\/body>/m).flatten.first}/)
59
61
  end
60
62
 
61
63
  it 'should return all bodies in history (though hidden by css)' do
62
64
  @middleware.call @env
63
65
  @middleware.app = lambda {|env| [200, {}, @body2]}
64
66
  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
+ body.to_s.should match(/#{@body.join.scan(/<body>(.*?)<\/body>/m).flatten.first}/)
68
+ body.to_s.should match(/#{@body2.join.scan(/<body>(.*?)<\/body>/m).flatten.first}/)
69
+ body.to_s.scan(/class="__reshow_body__"/).count.should == 2
70
+ end
71
+
72
+ it 'should insert a <link> tag for each version in history' do
73
+ status, headers, body = @middleware.call @env
74
+ count = body.to_s.scan(/<link.*?>/).count
75
+ @middleware.app = lambda {|env| [200, {}, @body2]}
76
+ status, headers, body = @middleware.call @env
77
+ body.to_s.scan(/<link.*?>/).count.should == count + 1
78
+ end
79
+
80
+ it 'should save external stylesheets and insert them as separate <link> tags' do
81
+ status, headers, body = @middleware.call @env
82
+ body.to_s.should match(/<link.*?href='\/__reshow__\/assets\?path=\%2F&version=0'.*?>/)
83
+ app = lambda {|env| [200, {}, @body2]}
84
+ @middleware.app = Rack::Static.new(app, :urls => ["/public"], :@root => @root)
85
+ status, headers, body = @middleware.call @env
86
+ body.to_s.should match(/<link.*?href='\/__reshow__\/assets\?path=\%2F&version=0'.*?>/)
87
+ body.to_s.should match(/<link.*?href='\/__reshow__\/assets\?path=\%2F&version=1'.*?>/)
88
+ end
89
+
90
+ it 'should serve versioned stylesheets' do
91
+ @middleware.call @env
92
+ status, headers, body = @middleware.call Rack::MockRequest.env_for '/__reshow__/assets?path=%2F&version=0'
93
+ body.to_s.should eql(@css)
94
+ end
95
+
96
+ it 'should insert a Reshow bar to allow users to view different versions' do
97
+ status, headers, body = @middleware.call @env
98
+ body.to_s[/id="__reshow_bar__"/].should_not be_nil
67
99
  end
68
100
 
69
101
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-reshow
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - ecin
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-01-07 00:00:00 -04:00
12
+ date: 2010-01-12 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -54,6 +54,10 @@ files:
54
54
  - lib/rack/__reshow__/reshow.css
55
55
  - lib/rack/__reshow__/reshow.js
56
56
  - lib/rack/reshow.rb
57
+ - spec/public/v1.css
58
+ - spec/public/v1.html
59
+ - spec/public/v2.css
60
+ - spec/public/v2.html
57
61
  - spec/reshow_spec.rb
58
62
  - spec/spec.opts
59
63
  - spec/spec_helper.rb