rack-backbone 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +22 -0
- data/.travis.yml +11 -0
- data/CHANGES.md +7 -0
- data/Gemfile +26 -0
- data/LICENCE.txt +22 -0
- data/README.md +82 -0
- data/Rakefile +73 -0
- data/examples/config.rb +144 -0
- data/examples/config.ru +11 -0
- data/lib/rack/backbone.rb +125 -0
- data/lib/rack/backbone/version.rb +14 -0
- data/rack-backbone.gemspec +25 -0
- data/spec/rack_jquery_spec.rb +144 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/support/shared/all_pages.rb +14 -0
- metadata +129 -0
data/.gitignore
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
.yardoc
|
6
|
+
Gemfile.lock
|
7
|
+
InstalledFiles
|
8
|
+
_yardoc
|
9
|
+
coverage
|
10
|
+
doc/
|
11
|
+
lib/bundler/man
|
12
|
+
pkg
|
13
|
+
rdoc
|
14
|
+
spec/reports
|
15
|
+
test/tmp
|
16
|
+
test/version_tmp
|
17
|
+
tmp
|
18
|
+
.rbx/
|
19
|
+
.rspec
|
20
|
+
vendor/ruby/
|
21
|
+
vendor/
|
22
|
+
bin/
|
data/.travis.yml
ADDED
data/CHANGES.md
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in rack-jquery.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem 'rspec'
|
8
|
+
gem 'simplecov'
|
9
|
+
gem 'rack-test'
|
10
|
+
gem "timecop"
|
11
|
+
end
|
12
|
+
|
13
|
+
group :examples do
|
14
|
+
gem "sinatra"
|
15
|
+
gem "haml"
|
16
|
+
gem "rack-lodash"
|
17
|
+
gem "rack-jquery"
|
18
|
+
end
|
19
|
+
|
20
|
+
group :development do
|
21
|
+
gem "wirble"
|
22
|
+
gem "pry"
|
23
|
+
gem "pry-nav"
|
24
|
+
gem "yard"
|
25
|
+
gem "maruku"
|
26
|
+
end
|
data/LICENCE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Iain Barnett
|
2
|
+
|
3
|
+
MIT Licence
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# Rack::Backbone
|
2
|
+
|
3
|
+
[Backbone](http://backbone.com/download/) CDN script tags and fallback in one neat package.
|
4
|
+
|
5
|
+
### Build status ###
|
6
|
+
|
7
|
+
Master branch:
|
8
|
+
[![Build Status](https://secure.travis-ci.org/yb66/rack-backbone.png?branch=master)](http://travis-ci.org/yb66/rack-backbone)
|
9
|
+
|
10
|
+
### Why? ###
|
11
|
+
|
12
|
+
I get tired of copy and pasting and downloading and moving… Backbone files and script tags etc. This does it for me, and keeps version management nice 'n' easy.
|
13
|
+
|
14
|
+
### Note ###
|
15
|
+
|
16
|
+
This library does not supply any other dependencies (like underscore.js/lo-dash.js) - that is up to you to provide!
|
17
|
+
|
18
|
+
### Usage ###
|
19
|
+
|
20
|
+
Have a look in the examples directory, but here's a snippet.
|
21
|
+
|
22
|
+
* Install it (see below)
|
23
|
+
* `require 'rack/backbone'`.
|
24
|
+
* If you want fallback then add this to your middleware stack: `use Rack::Backbone`
|
25
|
+
* Put this in the head of your layout (the example is Haml but you can use whatever you like) and pass it the Rack env:
|
26
|
+
|
27
|
+
<pre><code>
|
28
|
+
%head
|
29
|
+
= Rack::Backbone.cdn( env )
|
30
|
+
</code></pre>
|
31
|
+
|
32
|
+
Now you have the script tags to Cloudflare's CDN (or you can use jsdelivr, see the docs).
|
33
|
+
|
34
|
+
It also adds in a bit of javascript that will load in a locally kept version of Backbone, just incase the CDN is unreachable. The script will use the "/js/backbone-1.0.0-min.js" path (or, instead of 1.0.0, whatever is in {Rack::Backbone::VERSION}). You can change the "/js" bit if you like (see the docs).
|
35
|
+
|
36
|
+
That was easy.
|
37
|
+
|
38
|
+
### Version numbers ###
|
39
|
+
|
40
|
+
This library uses [semver](http://semver.org/) to version the **library**. That means the library version is ***not*** an indicator of quality but a way to manage changes. The version of Backbone can be found in the lib/rack/backbone/version.rb file, or via the {Rack::Backbone::BACKBONE_VERSION} constant.
|
41
|
+
|
42
|
+
On top of that, version numbers will also change when new releases of Backbone are supported.
|
43
|
+
|
44
|
+
* If Backbone makes a major version jump, then this library will make a ***minor*** jump. That is because the API for the library has not really changed, but it is *possibly* a change that will break things.
|
45
|
+
* If Backbone makes a minor version jump, then so will this library, for the same reason as above.
|
46
|
+
* I doubt point releases will be followed, but if so, it will also precipitate a minor jump in this library's version number. That's because even though Backbone feel it's a point release, I'm not them, my responsibility is to users of this library and I'll take the cautious approach of making it a minor version number change.
|
47
|
+
|
48
|
+
As an example, if the current library version was 1.0.0 and Backbone was at 2.0.0 and I made a change that I felt was major and breaking (to the Ruby library), I'd bump Rack::Backbone's version to 2.0.0. That the version numbers match between Rack::Backbone and the Backbone script is of no significance, it's just coincidental.
|
49
|
+
If then Backbone went to v2.1.0 and I decided to support that, I'd make the changes and bump Rack::Backbone's version to 2.1.0. That the version numbers match between Rack::Backbone and the Backbone script is of no significance, it's just coincidental.
|
50
|
+
If then I made a minor change to the library's API that could be breaking I'd bump it to 2.2.0.
|
51
|
+
If I then added some more instructions I'd bump Rack::Backbone's version to 2.2.1.
|
52
|
+
If then Backbone released version 3.0.0, I'd add it to the library, and bump Rack::Backbone's version to 2.3.0.
|
53
|
+
|
54
|
+
Only one version of Backbone will be supported at a time. This is because the fallback script is shipped with the gem and I'd like to keep it as light as possible. It's also a headache to have more than one.
|
55
|
+
|
56
|
+
So basically, if you want to use a specific version of Backbone, look for the library version that supports it via the {Rack::Backbone::BACKBONE_VERSION} constant. Don't rely on the version numbers of *this* library to tell you anything other than compatibility between versions of this library.
|
57
|
+
|
58
|
+
### Installation
|
59
|
+
|
60
|
+
Add this line to your application's Gemfile:
|
61
|
+
|
62
|
+
gem 'rack-backbone'
|
63
|
+
|
64
|
+
And then execute:
|
65
|
+
|
66
|
+
$ bundle
|
67
|
+
|
68
|
+
Or install it yourself as:
|
69
|
+
|
70
|
+
$ gem install rack-backbone
|
71
|
+
|
72
|
+
### Contributing ###
|
73
|
+
|
74
|
+
1. Fork it
|
75
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
76
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
77
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
78
|
+
5. Create new Pull Request
|
79
|
+
|
80
|
+
### Licences ###
|
81
|
+
|
82
|
+
The licence for this library is contained in LICENCE.txt. The Backbone library licence is contained in BACKBONE-LICENCE.txt.
|
data/Rakefile
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
|
4
|
+
desc "(Re-) generate documentation and place it in the docs/ dir. Open the index.html file in there to read it."
|
5
|
+
task :docs => [:"docs:environment", :"docs:yard"]
|
6
|
+
namespace :docs do
|
7
|
+
|
8
|
+
task :environment do
|
9
|
+
ENV["RACK_ENV"] = "documentation"
|
10
|
+
end
|
11
|
+
|
12
|
+
require 'yard'
|
13
|
+
|
14
|
+
YARD::Rake::YardocTask.new :yard do |t|
|
15
|
+
t.files = ['lib/**/*.rb', 'app/*.rb', 'spec/**/*.rb']
|
16
|
+
t.options = ['-odocs/'] # optional
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
task :default => "spec"
|
22
|
+
|
23
|
+
task :spec => :"spec:run"
|
24
|
+
task :rspec => :spec
|
25
|
+
namespace :spec do
|
26
|
+
task :environment do
|
27
|
+
ENV["RACK_ENV"] = "test"
|
28
|
+
end
|
29
|
+
|
30
|
+
desc "Run specs"
|
31
|
+
task :run, [:any_args] => :"spec:environment" do |t,args|
|
32
|
+
warn "Entering spec task."
|
33
|
+
any_args = args[:any_args] || ""
|
34
|
+
cmd = "bin/rspec #{any_args}"
|
35
|
+
warn cmd
|
36
|
+
system cmd
|
37
|
+
end
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
namespace :examples do
|
42
|
+
|
43
|
+
desc "Run the examples."
|
44
|
+
task :run do
|
45
|
+
exec "bundle exec rackup examples/config.ru"
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
namespace :cdn do
|
52
|
+
require 'open3'
|
53
|
+
desc "An availability check, for sanity"
|
54
|
+
task :check do
|
55
|
+
require_relative './lib/rack/backbone.rb'
|
56
|
+
Rack::Backbone::CDN.constants.each do |const|
|
57
|
+
url = "#{Rack::Backbone::CDN.const_get(const)}"
|
58
|
+
url = "http:#{url}" unless url.start_with? "http"
|
59
|
+
cmd = "curl -I #{url}"
|
60
|
+
puts cmd
|
61
|
+
puts catch(:status) {
|
62
|
+
Open3.popen3(cmd) do |_,stdout,_|
|
63
|
+
line = stdout.gets
|
64
|
+
throw :status, "Nothing for #{const}" if line.nil?
|
65
|
+
puts line.match("HTTP/1.1 404 Not Found") ?
|
66
|
+
"FAILED: #{const}" :
|
67
|
+
"PASSED: #{const}"
|
68
|
+
end
|
69
|
+
}
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
data/examples/config.rb
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
require 'sinatra/base'
|
2
|
+
require 'haml'
|
3
|
+
require 'rack/backbone'
|
4
|
+
require 'rack/lodash'
|
5
|
+
require 'rack/jquery'
|
6
|
+
|
7
|
+
class App < Sinatra::Base
|
8
|
+
|
9
|
+
enable :inline_templates
|
10
|
+
use Rack::JQuery # << These are just here for the example.
|
11
|
+
use Rack::Lodash # << Just make sure any dependencies are
|
12
|
+
# available, however you decide to do that.
|
13
|
+
use Rack::Backbone
|
14
|
+
|
15
|
+
get "/" do
|
16
|
+
output = <<STR
|
17
|
+
!!!
|
18
|
+
%body
|
19
|
+
%ul
|
20
|
+
%li
|
21
|
+
%a{ href: "/jsdelivr-cdn"} jsdelivr-cdn
|
22
|
+
%li
|
23
|
+
%a{ href: "/cloudflare-cdn"} cloudflare-cdn
|
24
|
+
%li
|
25
|
+
%a{ href: "/unspecified-cdn"} unspecified-cdn
|
26
|
+
STR
|
27
|
+
haml output
|
28
|
+
end
|
29
|
+
|
30
|
+
get "/jsdelivr-cdn" do
|
31
|
+
haml :index, :layout => :jsdelivr
|
32
|
+
end
|
33
|
+
|
34
|
+
get "/cloudflare-cdn" do
|
35
|
+
haml :index, :layout => :cloudflare
|
36
|
+
end
|
37
|
+
|
38
|
+
get "/unspecified-cdn" do
|
39
|
+
haml :index, :layout => :unspecified
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
class AppWithDefaults < Sinatra::Base
|
45
|
+
|
46
|
+
enable :inline_templates
|
47
|
+
use Rack::JQuery
|
48
|
+
use Rack::Lodash
|
49
|
+
use Rack::Backbone, :organisation => :cloudflare
|
50
|
+
|
51
|
+
get "/" do
|
52
|
+
output = <<STR
|
53
|
+
!!!
|
54
|
+
%body
|
55
|
+
%ul
|
56
|
+
%li
|
57
|
+
%a{ href: "/jsdelivr-cdn"} jsdelivr-cdn
|
58
|
+
%li
|
59
|
+
%a{ href: "/cloudflare-cdn"} cloudflare-cdn
|
60
|
+
%li
|
61
|
+
%a{ href: "/unspecified-cdn"} unspecified-cdn
|
62
|
+
STR
|
63
|
+
haml output
|
64
|
+
end
|
65
|
+
|
66
|
+
get "/jsdelivr-cdn" do
|
67
|
+
haml :index, :layout => :jsdelivr
|
68
|
+
end
|
69
|
+
|
70
|
+
get "/cloudflare-cdn" do
|
71
|
+
haml :index, :layout => :cloudflare
|
72
|
+
end
|
73
|
+
|
74
|
+
get "/unspecified-cdn" do
|
75
|
+
haml :index, :layout => :unspecified
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
__END__
|
80
|
+
|
81
|
+
@@jsdelivr
|
82
|
+
%html
|
83
|
+
%head
|
84
|
+
= Rack::JQuery.cdn( env )
|
85
|
+
= Rack::Lodash.cdn( env )
|
86
|
+
= Rack::Backbone.cdn( env, :organisation => :jsdelivr )
|
87
|
+
= yield
|
88
|
+
|
89
|
+
@@cloudflare
|
90
|
+
%html
|
91
|
+
%head
|
92
|
+
= Rack::JQuery.cdn( env )
|
93
|
+
= Rack::Lodash.cdn( env )
|
94
|
+
= Rack::Backbone.cdn( env, :organisation => :cloudflare )
|
95
|
+
= yield
|
96
|
+
|
97
|
+
@@unspecified
|
98
|
+
%html
|
99
|
+
%head
|
100
|
+
= Rack::JQuery.cdn( env )
|
101
|
+
= Rack::Lodash.cdn( env )
|
102
|
+
= Rack::Backbone.cdn(env)
|
103
|
+
= yield
|
104
|
+
|
105
|
+
@@index
|
106
|
+
|
107
|
+
%input{ type: "text", placeholder: "Enter friend's name", id: "input"}
|
108
|
+
%button#add
|
109
|
+
Add Friend
|
110
|
+
|
111
|
+
%ul#friends
|
112
|
+
|
113
|
+
:javascript
|
114
|
+
$(function() {
|
115
|
+
|
116
|
+
FriendList = Backbone.Collection.extend({
|
117
|
+
initialize: function(){
|
118
|
+
}
|
119
|
+
});
|
120
|
+
|
121
|
+
FriendView = Backbone.View.extend({
|
122
|
+
tagName: 'li',
|
123
|
+
events: {
|
124
|
+
'click #add': 'getFriend',
|
125
|
+
},
|
126
|
+
initialize: function() {
|
127
|
+
var thisView = this;
|
128
|
+
this.friendslist = new FriendList;
|
129
|
+
_.bindAll(this, 'render');
|
130
|
+
this.friendslist.bind("add", function( model ){
|
131
|
+
thisView.render( model );
|
132
|
+
})
|
133
|
+
},
|
134
|
+
getFriend: function() {
|
135
|
+
var friend_name = $('#input').val();
|
136
|
+
this.friendslist.add( {name: friend_name} );
|
137
|
+
},
|
138
|
+
render: function( model ) {
|
139
|
+
$("#friends").append("<li>"+ model.get("name")+"</li>");
|
140
|
+
},
|
141
|
+
});
|
142
|
+
|
143
|
+
var view = new FriendView({el: 'body'});
|
144
|
+
});
|
data/examples/config.ru
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
require "rack/backbone/version"
|
2
|
+
require "rack/jquery/helpers"
|
3
|
+
|
4
|
+
# @see http://rack.github.io/
|
5
|
+
module Rack
|
6
|
+
|
7
|
+
# Backbone CDN script tags and fallback in one neat package.
|
8
|
+
class Backbone
|
9
|
+
include Rack::JQuery::Helpers
|
10
|
+
|
11
|
+
# Current file name of fallback.
|
12
|
+
BACKBONE_FILE_NAME = "backbone-#{BACKBONE_VERSION}-min.js"
|
13
|
+
|
14
|
+
# Fallback source map file name.
|
15
|
+
BACKBONE_SOURCE_MAP = "backbone-#{BACKBONE_VERSION}-min.map"
|
16
|
+
|
17
|
+
|
18
|
+
# Namespaced CDNs for convenience.
|
19
|
+
module CDN
|
20
|
+
|
21
|
+
# Script tags for the Cloudflare CDN
|
22
|
+
CLOUDFLARE = "//cdnjs.cloudflare.com/ajax/libs/backbone.js/1.0.0/backbone-min.js"
|
23
|
+
|
24
|
+
# Script tags for the jsdelivr CDN
|
25
|
+
JSDELIVR = "//cdn.jsdelivr.net/backbonejs/1.0.0/backbone-min.js"
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
# This javascript checks if the Backbone object has loaded. If not, that most likely means the CDN is unreachable, so it uses the local minified Backbone.
|
30
|
+
FALLBACK = <<STR
|
31
|
+
<script type="text/javascript">
|
32
|
+
if (typeof Backbone == 'undefined') {
|
33
|
+
document.write(unescape("%3Cscript src='/js/#{BACKBONE_FILE_NAME}' type='text/javascript'%3E%3C/script%3E"))
|
34
|
+
};
|
35
|
+
</script>
|
36
|
+
STR
|
37
|
+
|
38
|
+
# @param [Hash] env The rack env hash.
|
39
|
+
# @param [Symbol] organisation Choose which CDN to use, either :jsdelivr, or :cloudflare (the default). This will override anything set via the `use` statement.
|
40
|
+
# @return [String] The HTML script tags to get the CDN.
|
41
|
+
def self.cdn( env, options={} )
|
42
|
+
if env.nil? || env.has_key?(:organisation)
|
43
|
+
fail ArgumentError, "The Rack::Backbone.cdn method needs the Rack environment passed to it, or at the very least, an empty hash."
|
44
|
+
end
|
45
|
+
|
46
|
+
organisation = options[:organisation] ||
|
47
|
+
env["rack.backbone.organisation"] ||
|
48
|
+
:media_temple
|
49
|
+
|
50
|
+
script = case organisation
|
51
|
+
when :cloudflare
|
52
|
+
CDN::CLOUDFLARE
|
53
|
+
when :jsdelivr
|
54
|
+
CDN::JSDELIVR
|
55
|
+
else
|
56
|
+
CDN::CLOUDFLARE
|
57
|
+
end
|
58
|
+
"<script src='#{script}'></script>\n#{FALLBACK}"
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
# Default options hash for the middleware.
|
63
|
+
DEFAULT_OPTIONS = {
|
64
|
+
:http_path => "/js"
|
65
|
+
}
|
66
|
+
|
67
|
+
|
68
|
+
# @param [#call] app
|
69
|
+
# @param [Hash] options
|
70
|
+
# @option options [String] :http_path If you wish the Backbone fallback route to be "/js/backbone-1.9.1.min.js" (or whichever version this is at) then do nothing, that's the default. If you want the path to be "/assets/javascripts/backbone-1.9.1.min.js" then pass in `:http_path => "/assets/javascripts".
|
71
|
+
# @option options [Symbol] :organisation see {Rack::Backbone.cdn}
|
72
|
+
# @example
|
73
|
+
# # The default:
|
74
|
+
# use Rack::Backbone
|
75
|
+
#
|
76
|
+
# # With a different route to the fallback:
|
77
|
+
# use Rack::Backbone, :http_path => "/assets/js"
|
78
|
+
#
|
79
|
+
# # With a default organisation:
|
80
|
+
# use Rack::Backbone, :organisation => :cloudflare
|
81
|
+
def initialize( app, options={} )
|
82
|
+
@app, @options = app, DEFAULT_OPTIONS.merge(options)
|
83
|
+
@http_path_to_backbone = ::File.join @options[:http_path], BACKBONE_FILE_NAME
|
84
|
+
@http_path_to_source_map = ::File.join @options[:http_path], BACKBONE_SOURCE_MAP
|
85
|
+
@organisation = options.fetch :organisation, :media_temple
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
# @param [Hash] env Rack request environment hash.
|
90
|
+
def call( env )
|
91
|
+
dup._call env
|
92
|
+
end
|
93
|
+
|
94
|
+
|
95
|
+
# For thread safety
|
96
|
+
# @param (see #call)
|
97
|
+
def _call( env )
|
98
|
+
request = Rack::Request.new(env.dup)
|
99
|
+
env.merge! "rack.backbone.organisation" => @organisation
|
100
|
+
if request.path_info == @http_path_to_backbone
|
101
|
+
response = Rack::Response.new
|
102
|
+
# for caching
|
103
|
+
response.headers.merge! caching_headers( BACKBONE_FILE_NAME, BACKBONE_VERSION_DATE)
|
104
|
+
|
105
|
+
# There's no need to test if the IF_MODIFIED_SINCE against the release date because the header will only be passed if the file was previously accessed by the requester, and the file is never updated. If it is updated then it is accessed by a different path.
|
106
|
+
if request.env['HTTP_IF_MODIFIED_SINCE']
|
107
|
+
response.status = 304
|
108
|
+
else
|
109
|
+
response.status = 200
|
110
|
+
response.write ::File.read( ::File.expand_path "../../../vendor/assets/javascripts/#{BACKBONE_FILE_NAME}", __FILE__)
|
111
|
+
end
|
112
|
+
response.finish
|
113
|
+
elsif request.path_info == @http_path_to_source_map
|
114
|
+
response = Rack::Response.new
|
115
|
+
# No need for caching with the source map
|
116
|
+
response.status = 200
|
117
|
+
response.write ::File.read( ::File.expand_path "../../../vendor/assets/javascripts/#{BACKBONE_SOURCE_MAP}", __FILE__)
|
118
|
+
response.finish
|
119
|
+
else
|
120
|
+
@app.call(env)
|
121
|
+
end
|
122
|
+
end # call
|
123
|
+
|
124
|
+
end
|
125
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Rack
|
2
|
+
class Backbone
|
3
|
+
|
4
|
+
# the version of this library
|
5
|
+
VERSION = "0.0.1"
|
6
|
+
|
7
|
+
# the version of Backbone it supports.
|
8
|
+
BACKBONE_VERSION = "1.0.0"
|
9
|
+
|
10
|
+
# This is the release date of the Backbone file, it makes an easy "Last-Modified" date for setting the headers around caching.
|
11
|
+
# @todo remember to change Last-Modified with each release!
|
12
|
+
BACKBONE_VERSION_DATE = "Wed, 20 Mar 2013 12:13:55 +0000"
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'rack/backbone/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "rack-backbone"
|
8
|
+
spec.version = Rack::Backbone::VERSION
|
9
|
+
spec.authors = ["Iain Barnett"]
|
10
|
+
spec.email = ["iainspeed@gmail.com"]
|
11
|
+
spec.description = %Q{Backbone.js CDN script tags and fallback in one neat package. Current version is for Backbone v#{Rack::Backbone::BACKBONE_VERSION}}
|
12
|
+
spec.summary = %q{The description says it all.}
|
13
|
+
spec.homepage = "https://github.com/yb66/rack-backbone"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/).reject{|x| x.start_with?("vendor") && !x.include?(Rack::Backbone::BACKBONE_VERSION) }
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.2"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_dependency("rack")
|
24
|
+
spec.add_dependency("rack-jquery-helpers")
|
25
|
+
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
require_relative "../lib/rack/backbone.rb"
|
5
|
+
|
6
|
+
describe "The class methods" do
|
7
|
+
let(:env) { {} }
|
8
|
+
subject { Rack::Backbone.cdn env, :organisation => organisation }
|
9
|
+
|
10
|
+
context "Given the organisation option" do
|
11
|
+
context "of nil (the default)" do
|
12
|
+
let(:organisation) { nil }
|
13
|
+
it { should == "<script src='#{Rack::Backbone::CDN::CLOUDFLARE}'></script>\n#{Rack::Backbone::FALLBACK}" }
|
14
|
+
end
|
15
|
+
context "of :jsdelivr" do
|
16
|
+
let(:organisation) { :jsdelivr }
|
17
|
+
it { should == "<script src='#{Rack::Backbone::CDN::JSDELIVR}'></script>\n#{Rack::Backbone::FALLBACK}" }
|
18
|
+
end
|
19
|
+
context "of :cloudflare" do
|
20
|
+
let(:organisation) { :cloudflare }
|
21
|
+
it { should == "<script src='#{Rack::Backbone::CDN::CLOUDFLARE}'></script>\n#{Rack::Backbone::FALLBACK}" }
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "Given no Rack env argument" do
|
26
|
+
it "should fail and give a message" do
|
27
|
+
expect{ Rack::Backbone.cdn nil }.to raise_error(ArgumentError)
|
28
|
+
end
|
29
|
+
|
30
|
+
context "and an organisation option" do
|
31
|
+
it "should fail and give a message" do
|
32
|
+
expect{ Rack::Backbone.cdn nil, {:organisation => :jsdelivr} }.to raise_error(ArgumentError)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe "Inserting the CDN" do
|
39
|
+
|
40
|
+
# These check the default is overriden
|
41
|
+
# when `cdn` is given a value
|
42
|
+
# but when not, the default is used.
|
43
|
+
context "When given a default" do
|
44
|
+
include_context "All routes" do
|
45
|
+
let(:app){ AppWithDefaults }
|
46
|
+
end
|
47
|
+
context "Check the examples run at all" do
|
48
|
+
before do
|
49
|
+
get "/"
|
50
|
+
end
|
51
|
+
it_should_behave_like "Any route"
|
52
|
+
end
|
53
|
+
context "jsdelivr CDN" do
|
54
|
+
before do
|
55
|
+
get "/jsdelivr-cdn"
|
56
|
+
end
|
57
|
+
it_should_behave_like "Any route"
|
58
|
+
subject { last_response.body }
|
59
|
+
let(:expected) { Rack::Backbone::CDN::JSDELIVR }
|
60
|
+
it { should include expected }
|
61
|
+
end
|
62
|
+
context "Unspecified CDN" do
|
63
|
+
before do
|
64
|
+
get "/unspecified-cdn"
|
65
|
+
end
|
66
|
+
it_should_behave_like "Any route"
|
67
|
+
subject { last_response.body }
|
68
|
+
let(:expected) { Rack::Backbone::CDN::CLOUDFLARE }
|
69
|
+
it { should include expected }
|
70
|
+
end
|
71
|
+
context "Cloudflare CDN" do
|
72
|
+
before do
|
73
|
+
get "/cloudflare-cdn"
|
74
|
+
end
|
75
|
+
it_should_behave_like "Any route"
|
76
|
+
subject { last_response.body }
|
77
|
+
let(:expected) { Rack::Backbone::CDN::CLOUDFLARE }
|
78
|
+
it { should include expected }
|
79
|
+
end
|
80
|
+
end
|
81
|
+
context "When not given a default" do
|
82
|
+
include_context "All routes"
|
83
|
+
context "Check the examples run at all" do
|
84
|
+
before do
|
85
|
+
get "/"
|
86
|
+
end
|
87
|
+
it_should_behave_like "Any route"
|
88
|
+
end
|
89
|
+
context "jsdelivr CDN" do
|
90
|
+
before do
|
91
|
+
get "/jsdelivr-cdn"
|
92
|
+
end
|
93
|
+
it_should_behave_like "Any route"
|
94
|
+
subject { last_response.body }
|
95
|
+
let(:expected) { Rack::Backbone::CDN::JSDELIVR }
|
96
|
+
it { should include expected }
|
97
|
+
end
|
98
|
+
context "Unspecified CDN" do
|
99
|
+
before do
|
100
|
+
get "/unspecified-cdn"
|
101
|
+
end
|
102
|
+
it_should_behave_like "Any route"
|
103
|
+
subject { last_response.body }
|
104
|
+
let(:expected) { Rack::Backbone::CDN::CLOUDFLARE }
|
105
|
+
it { should include expected }
|
106
|
+
end
|
107
|
+
context "Cloudflare CDN" do
|
108
|
+
before do
|
109
|
+
get "/cloudflare-cdn"
|
110
|
+
end
|
111
|
+
it_should_behave_like "Any route"
|
112
|
+
subject { last_response.body }
|
113
|
+
let(:expected) { Rack::Backbone::CDN::CLOUDFLARE }
|
114
|
+
it { should include expected }
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
require 'timecop'
|
121
|
+
require 'time'
|
122
|
+
|
123
|
+
describe "Serving the fallback backbone" do
|
124
|
+
include_context "All routes"
|
125
|
+
before do
|
126
|
+
get "/js/backbone-#{Rack::Backbone::BACKBONE_VERSION}-min.js"
|
127
|
+
end
|
128
|
+
it_should_behave_like "Any route"
|
129
|
+
subject { last_response.body }
|
130
|
+
it { should start_with "(function(){var t=this;var e=t.Backbone;" }
|
131
|
+
|
132
|
+
context "Re requests" do
|
133
|
+
before do
|
134
|
+
at_start = Time.parse(Rack::Backbone::BACKBONE_VERSION_DATE) + 60 * 60 * 24 * 180
|
135
|
+
Timecop.freeze at_start
|
136
|
+
get "/js/backbone-#{Rack::Backbone::BACKBONE_VERSION}-min.js"
|
137
|
+
Timecop.travel Time.now + 86400 # add a day
|
138
|
+
get "/js/backbone-#{Rack::Backbone::BACKBONE_VERSION}-min.js", {}, {"HTTP_IF_MODIFIED_SINCE" => Rack::Utils.rfc2109(at_start) }
|
139
|
+
end
|
140
|
+
subject { last_response }
|
141
|
+
its(:status) { should == 304 }
|
142
|
+
|
143
|
+
end
|
144
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
require 'rspec'
|
4
|
+
Spec_dir = File.expand_path( File.dirname __FILE__ )
|
5
|
+
|
6
|
+
|
7
|
+
# code coverage
|
8
|
+
require 'simplecov'
|
9
|
+
SimpleCov.start do
|
10
|
+
add_filter "/vendor/"
|
11
|
+
add_filter "/bin/"
|
12
|
+
add_filter "/spec/"
|
13
|
+
end
|
14
|
+
|
15
|
+
require "rack/test"
|
16
|
+
ENV['RACK_ENV'] ||= 'test'
|
17
|
+
ENV["EXPECT_WITH"] ||= "racktest"
|
18
|
+
|
19
|
+
|
20
|
+
Dir[ File.join( Spec_dir, "/support/**/*.rb")].each do |f|
|
21
|
+
require f
|
22
|
+
end
|
23
|
+
|
24
|
+
RSpec.configure do |config|
|
25
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
26
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
|
3
|
+
config_path = File.expand_path '../../../examples/config.rb', File.dirname(__FILE__)
|
4
|
+
require_relative config_path
|
5
|
+
|
6
|
+
shared_context "All routes" do
|
7
|
+
include Rack::Test::Methods
|
8
|
+
let(:app){ App }
|
9
|
+
end
|
10
|
+
|
11
|
+
shared_examples_for "Any route" do
|
12
|
+
subject { last_response }
|
13
|
+
it { should be_ok }
|
14
|
+
end
|
metadata
ADDED
@@ -0,0 +1,129 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-backbone
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Iain Barnett
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-09-09 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.2'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.2'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rack
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rack-jquery-helpers
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
description: Backbone.js CDN script tags and fallback in one neat package. Current
|
79
|
+
version is for Backbone v1.0.0
|
80
|
+
email:
|
81
|
+
- iainspeed@gmail.com
|
82
|
+
executables: []
|
83
|
+
extensions: []
|
84
|
+
extra_rdoc_files: []
|
85
|
+
files:
|
86
|
+
- .gitignore
|
87
|
+
- .travis.yml
|
88
|
+
- CHANGES.md
|
89
|
+
- Gemfile
|
90
|
+
- LICENCE.txt
|
91
|
+
- README.md
|
92
|
+
- Rakefile
|
93
|
+
- examples/config.rb
|
94
|
+
- examples/config.ru
|
95
|
+
- lib/rack/backbone.rb
|
96
|
+
- lib/rack/backbone/version.rb
|
97
|
+
- rack-backbone.gemspec
|
98
|
+
- spec/rack_jquery_spec.rb
|
99
|
+
- spec/spec_helper.rb
|
100
|
+
- spec/support/shared/all_pages.rb
|
101
|
+
homepage: https://github.com/yb66/rack-backbone
|
102
|
+
licenses:
|
103
|
+
- MIT
|
104
|
+
post_install_message:
|
105
|
+
rdoc_options: []
|
106
|
+
require_paths:
|
107
|
+
- lib
|
108
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
109
|
+
none: false
|
110
|
+
requirements:
|
111
|
+
- - ! '>='
|
112
|
+
- !ruby/object:Gem::Version
|
113
|
+
version: '0'
|
114
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
|
+
none: false
|
116
|
+
requirements:
|
117
|
+
- - ! '>='
|
118
|
+
- !ruby/object:Gem::Version
|
119
|
+
version: '0'
|
120
|
+
requirements: []
|
121
|
+
rubyforge_project:
|
122
|
+
rubygems_version: 1.8.25
|
123
|
+
signing_key:
|
124
|
+
specification_version: 3
|
125
|
+
summary: The description says it all.
|
126
|
+
test_files:
|
127
|
+
- spec/rack_jquery_spec.rb
|
128
|
+
- spec/spec_helper.rb
|
129
|
+
- spec/support/shared/all_pages.rb
|