qedproject 0.0.4
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/bin/qedproject +49 -0
- data/lib/qedproject/helpers.rb +17 -0
- data/lib/qedproject/libraries/backbone.rb +9 -0
- data/lib/qedproject/libraries/base.rb +105 -0
- data/lib/qedproject/libraries/jquery.rb +9 -0
- data/lib/qedproject/libraries/jquerytmpl.rb +9 -0
- data/lib/qedproject/libraries/knockout.rb +9 -0
- data/lib/qedproject/libraries/skeleton.rb +21 -0
- data/lib/qedproject/project.rb +185 -0
- data/lib/qedproject/version.rb +3 -0
- data/lib/qedproject.rb +14 -0
- data/templates/Guardfile +29 -0
- data/templates/Rakefile +25 -0
- data/templates/assets.yml +10 -0
- data/templates/index.html +35 -0
- data/templates/sampleSpec.coffee +0 -0
- data/templates/sampleSpec.js +7 -0
- data/templates/suite.html +23 -0
- data/vendor/backbone/VERSION +1 -0
- data/vendor/backbone/backbone-min.js +33 -0
- data/vendor/backbone/json2.js +480 -0
- data/vendor/backbone/underscore-min.js +27 -0
- data/vendor/jasmine/lib/jasmine-1.0.2/jasmine-html.js +188 -0
- data/vendor/jasmine/lib/jasmine-1.0.2/jasmine.css +166 -0
- data/vendor/jasmine/lib/jasmine-1.0.2/jasmine.js +2421 -0
- data/vendor/jquery/VERSION +1 -0
- data/vendor/jquery/jquery-1.6.2.min.js +18 -0
- data/vendor/jquerytmpl/VERSION +1 -0
- data/vendor/jquerytmpl/jquery.tmpl.min.js +10 -0
- data/vendor/knockout/VERSION +1 -0
- data/vendor/knockout/knockout-1.2.1.js +76 -0
- data/vendor/skeleton/VERSION +1 -0
- data/vendor/skeleton/apple-touch-icon-114x114.png +0 -0
- data/vendor/skeleton/apple-touch-icon-72x72.png +0 -0
- data/vendor/skeleton/apple-touch-icon.png +0 -0
- data/vendor/skeleton/base.css +335 -0
- data/vendor/skeleton/favicon.ico +0 -0
- data/vendor/skeleton/layout.css +58 -0
- data/vendor/skeleton/skeleton.css +236 -0
- data/vendor/skeleton/tabs.js +42 -0
- data/vendor/skeleton/templates/index.html +94 -0
- metadata +219 -0
data/bin/qedproject
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require 'qedproject'
|
3
|
+
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
banner = "QEDProject #{QEDProject::VERSION} (C) 2011 Brian P. Hogan\n"
|
7
|
+
banner << "-" * banner.length
|
8
|
+
puts banner
|
9
|
+
|
10
|
+
options = {}
|
11
|
+
LIBRARIES = QEDProject::Libraries::Base.libs.keys
|
12
|
+
OptionParser.new do |opts|
|
13
|
+
opts.banner = "Usage: qedproject <projectname> [options]"
|
14
|
+
|
15
|
+
|
16
|
+
opts.on('-s', '--sass', "Use SASS") do
|
17
|
+
options[:sass] = true
|
18
|
+
end
|
19
|
+
|
20
|
+
opts.on('-c', '--coffee', "Use Coffeescript") do
|
21
|
+
options[:coffeescript] = true
|
22
|
+
end
|
23
|
+
|
24
|
+
opts.on('-a', '--assets', "Use Jammit to manage assets") do
|
25
|
+
options[:jammit] = true
|
26
|
+
end
|
27
|
+
|
28
|
+
opts.on('-t', '--testing', "Set up testing with Jasmine") do
|
29
|
+
options[:testing] = true
|
30
|
+
end
|
31
|
+
|
32
|
+
opts.on("-l", "--libs [LIBRARIES]", "comma-separated list of libraries to include.\nLibraries are: #{LIBRARIES.join(",")}") do |libs|
|
33
|
+
options[:libs] = libs.split(",").collect{ |f| f.to_sym }
|
34
|
+
end
|
35
|
+
end.parse!
|
36
|
+
options[:verbose] = true
|
37
|
+
project = ARGV[0]
|
38
|
+
|
39
|
+
if project.nil?
|
40
|
+
puts "Specify a project. Use qedproject -h for options."
|
41
|
+
else
|
42
|
+
begin
|
43
|
+
QEDProject::Project.create(project, options)
|
44
|
+
rescue QEDProject::BadLibraryError => e
|
45
|
+
puts e.message
|
46
|
+
puts "QEDProject supports #{LIBRARIES.join(",")}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module QEDProject
|
2
|
+
module Helpers
|
3
|
+
# Reads a template from the file system,
|
4
|
+
# evaluates it with ERB
|
5
|
+
# places it in the output folder specified.
|
6
|
+
# Takes the binding context as the last parameter
|
7
|
+
# so that ERb has access to instance variables, etc.
|
8
|
+
# This works similar to how Rails and Sinatra templates
|
9
|
+
# work.
|
10
|
+
def render_template_to_file(template, file, context)
|
11
|
+
t = File.read(File.join(self.template_root, template))
|
12
|
+
File.open(file, "w") do |f|
|
13
|
+
f << ERB.new(t, nil, "-").result(context)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
module QEDProject
|
2
|
+
module Libraries
|
3
|
+
|
4
|
+
class Base
|
5
|
+
include QEDProject::Helpers
|
6
|
+
|
7
|
+
attr_accessor :template_root, :lib_root, :project
|
8
|
+
class << self
|
9
|
+
|
10
|
+
attr_accessor :libs
|
11
|
+
|
12
|
+
# Support for DSL, for setting the library name
|
13
|
+
# when creating the adapter.
|
14
|
+
# Adds the library and class to QEDProject::Libraries::Base.libs hash
|
15
|
+
# and also creates a getter method on the adapter instance
|
16
|
+
def library(name)
|
17
|
+
QEDProject::Libraries::Base.libs ||= {}
|
18
|
+
QEDProject::Libraries::Base.libs[name] = self
|
19
|
+
class_eval do
|
20
|
+
define_method :library do
|
21
|
+
name
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def set_js_files(files)
|
27
|
+
# define class method
|
28
|
+
m = class << self; self; end
|
29
|
+
m.send :define_method, :js_files do
|
30
|
+
files
|
31
|
+
end
|
32
|
+
|
33
|
+
# define instance method
|
34
|
+
class_eval do
|
35
|
+
define_method :js_files do
|
36
|
+
files
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
# convenience method for the DSL for setting CSS files
|
42
|
+
def set_css_files(files)
|
43
|
+
# define class method to get the data out
|
44
|
+
m = class << self; self; end
|
45
|
+
m.send :define_method, :css_files do
|
46
|
+
files
|
47
|
+
end
|
48
|
+
|
49
|
+
class_eval do
|
50
|
+
define_method :css_files do
|
51
|
+
files
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
# convenience method for the DSL for setting image files.
|
58
|
+
def set_image_files(files)
|
59
|
+
|
60
|
+
m = class << self; self; end
|
61
|
+
m.send :define_method, :image_files do
|
62
|
+
files
|
63
|
+
end
|
64
|
+
|
65
|
+
class_eval do
|
66
|
+
define_method :image_files do
|
67
|
+
files
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def initialize(project)
|
74
|
+
@project = project
|
75
|
+
@lib_root = File.join(@project.vendor_root, self.library.to_s)
|
76
|
+
@template_root = File.join(@lib_root, "templates")
|
77
|
+
end
|
78
|
+
|
79
|
+
def generate!
|
80
|
+
self.copy_js if self.respond_to?(:js_files) && self.js_files.any?
|
81
|
+
self.copy_css if self.respond_to?(:css_files) && self.css_files.any?
|
82
|
+
self.copy_images if self.respond_to?(:image_files) && self.image_files.any?
|
83
|
+
end
|
84
|
+
|
85
|
+
def copy_images
|
86
|
+
self.image_files.each do |lib|
|
87
|
+
::FileUtils.cp_r File.join(self.lib_root, lib), File.join(self.project.path, self.project.images_path), :verbose => self.project.verbose
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def copy_css
|
92
|
+
self.css_files.each do |lib|
|
93
|
+
::FileUtils.cp_r File.join(self.lib_root, lib), File.join(self.project.path, self.project.css_path), :verbose => self.project.verbose
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def copy_js
|
98
|
+
self.js_files.each do |lib|
|
99
|
+
::FileUtils.cp_r File.join(self.lib_root, lib), File.join(self.project.path, self.project.js_path), :verbose => self.project.verbose
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module QEDProject
|
2
|
+
module Libraries
|
3
|
+
class Skeleton < QEDProject::Libraries::Base
|
4
|
+
library :skeleton
|
5
|
+
set_js_files ["tabs.js"]
|
6
|
+
set_css_files ["base.css", "skeleton.css", "layout.css" ]
|
7
|
+
set_image_files [
|
8
|
+
"apple-touch-icon-114x114.png",
|
9
|
+
"apple-touch-icon-72x72.png",
|
10
|
+
"apple-touch-icon.png",
|
11
|
+
"favicon.ico"
|
12
|
+
]
|
13
|
+
|
14
|
+
def generate!
|
15
|
+
super
|
16
|
+
render_template_to_file "index.html", File.join(self.project.path, "public", "index.html"), binding
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,185 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
require 'erb'
|
3
|
+
module QEDProject
|
4
|
+
|
5
|
+
class Project
|
6
|
+
|
7
|
+
include QEDProject::Helpers
|
8
|
+
|
9
|
+
attr_accessor :path, :libs, :coffeescript, :sass, :jammit,
|
10
|
+
:js_path, :css_path, :images_path, :verbose, :testing
|
11
|
+
# convenience method to create a new project.
|
12
|
+
# Simply call create with the project path and the options.
|
13
|
+
def self.create(project_path, options= {})
|
14
|
+
self.new(project_path, options).generate
|
15
|
+
end
|
16
|
+
|
17
|
+
def template_root
|
18
|
+
File.expand_path("../../../templates", __FILE__)
|
19
|
+
end
|
20
|
+
|
21
|
+
def vendor_root
|
22
|
+
File.expand_path("../../../vendor", __FILE__)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Creates a new Project instance.
|
26
|
+
# Options:
|
27
|
+
# :libs : A list of js libraries to include, Can be :backbone, :jquery, :knockout
|
28
|
+
# :jammit: boolean, should Jammit be included?
|
29
|
+
# :coffeescript : Should CoffeeScript support be included?
|
30
|
+
# :sass Should sass support be included?
|
31
|
+
def initialize(project_path, options = {})
|
32
|
+
self.path = project_path
|
33
|
+
self.process_options(options)
|
34
|
+
self.set_paths
|
35
|
+
end
|
36
|
+
|
37
|
+
|
38
|
+
# Convenience method for showing all of the JavaScript files that
|
39
|
+
# the project should contain. Good for creating asset lists
|
40
|
+
# and loading files in rendered templates
|
41
|
+
def js_assets
|
42
|
+
libs.inject([]) do |original, lib|
|
43
|
+
if QEDProject::Libraries::Base.libs[lib].respond_to?(:js_files)
|
44
|
+
original += QEDProject::Libraries::Base.libs[lib].js_files
|
45
|
+
else
|
46
|
+
original
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# Convenience method for showing all of the css files that
|
52
|
+
# the project should contain. Good for creating asset lists
|
53
|
+
# and loading files in rendered templates
|
54
|
+
def css_assets
|
55
|
+
libs.inject([]) do |original, lib|
|
56
|
+
if QEDProject::Libraries::Base.libs[lib].respond_to?(:css_files)
|
57
|
+
original += QEDProject::Libraries::Base.libs[lib].css_files
|
58
|
+
else
|
59
|
+
original
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# Sets instance methods with values from the options hash.
|
65
|
+
def process_options(options)
|
66
|
+
self.libs = options[:libs] || []
|
67
|
+
|
68
|
+
libs.each do |lib|
|
69
|
+
raise QEDProject::BadLibraryError, "#{lib} is not a valid library" unless QEDProject::Libraries::Base.libs.include? lib
|
70
|
+
end
|
71
|
+
|
72
|
+
self.jammit = options[:jammit]
|
73
|
+
self.sass = options[:sass]
|
74
|
+
self.coffeescript = options[:coffeescript]
|
75
|
+
self.verbose = options[:verbose]
|
76
|
+
self.testing = options[:testing]
|
77
|
+
end
|
78
|
+
|
79
|
+
# Set up the basic paths we'll use throughout
|
80
|
+
def set_paths
|
81
|
+
self.images_path = File.join("public", "images")
|
82
|
+
self.js_path = self.jammit ? "javascripts" : File.join("public", "javascripts")
|
83
|
+
self.css_path = self.jammit ? "stylesheets" : File.join("public", "stylesheets")
|
84
|
+
end
|
85
|
+
|
86
|
+
# We need a guardfile if the user is using jammit, sass, or coffeescript.
|
87
|
+
def needs_guardfile?
|
88
|
+
self.jammit || self.sass || self.coffeescript
|
89
|
+
end
|
90
|
+
|
91
|
+
# Only jammit needs a config folder for now.
|
92
|
+
def needs_config_folder?
|
93
|
+
self.jammit
|
94
|
+
end
|
95
|
+
|
96
|
+
# Start the project generation.
|
97
|
+
# Create the folder
|
98
|
+
# Get all of the libraries
|
99
|
+
# create an assets file if needed
|
100
|
+
# add the testing folder if needed
|
101
|
+
# create a guardfile if needed
|
102
|
+
def generate
|
103
|
+
self.create_project_skeleton
|
104
|
+
self.create_index
|
105
|
+
self.get_libraries if self.libs
|
106
|
+
self.create_asset_file if self.jammit
|
107
|
+
self.add_testing if self.testing
|
108
|
+
self.create_guardfile if self.needs_guardfile?
|
109
|
+
self.create_rakefile
|
110
|
+
end
|
111
|
+
|
112
|
+
# includes the Jasmine BDD framework for javascript testing
|
113
|
+
def add_testing
|
114
|
+
FileUtils.mkdir_p File.join(self.path, "spec"), :verbose => self.verbose
|
115
|
+
FileUtils.cp_r File.join(self.vendor_root, "jasmine", "lib"),
|
116
|
+
File.join(self.path, "spec", "lib"), :verbose => self.verbose
|
117
|
+
|
118
|
+
|
119
|
+
render_template_to_file "suite.html", File.join(self.path, "spec", "suite.html"), binding
|
120
|
+
if self.coffeescript
|
121
|
+
render_template_to_file "sampleSpec.coffee", File.join(self.path, "spec", "sampleSpec.coffee"), binding
|
122
|
+
else
|
123
|
+
render_template_to_file "sampleSpec.js", File.join(self.path, "spec", "sampleSpec.js"), binding
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
# Set up the main project skeleton
|
129
|
+
# project
|
130
|
+
# public/
|
131
|
+
# assets/ * only with assets
|
132
|
+
# images/
|
133
|
+
# javascripts/ * only without assets
|
134
|
+
# stylesheets/ * only without assets
|
135
|
+
# config/
|
136
|
+
# assets.yml * optional
|
137
|
+
# coffeescripts/ * optional
|
138
|
+
# sass/ * optional
|
139
|
+
# spec/ * optional
|
140
|
+
# Guardfile * optional
|
141
|
+
def create_project_skeleton
|
142
|
+
::FileUtils.mkdir_p( self.path, :verbose => self.verbose)
|
143
|
+
::FileUtils.mkdir_p( File.join(self.path, "public"), :verbose => self.verbose)
|
144
|
+
::FileUtils.mkdir_p( File.join(self.path, self.images_path), :verbose => self.verbose)
|
145
|
+
::FileUtils.mkdir_p( File.join(self.path, "tmp"), :verbose => self.verbose)
|
146
|
+
::FileUtils.mkdir_p( File.join(self.path, self.js_path), :verbose => self.verbose)
|
147
|
+
::FileUtils.mkdir_p( File.join(self.path, self.css_path), :verbose => self.verbose)
|
148
|
+
::FileUtils.mkdir_p( File.join(self.path, "config"), :verbose => self.verbose) if self.needs_config_folder?
|
149
|
+
::FileUtils.mkdir_p( File.join(self.path, "coffeescripts"), :verbose => self.verbose) if self.coffeescript
|
150
|
+
::FileUtils.mkdir_p( File.join(self.path, "sass"), :verbose => self.verbose) if self.sass
|
151
|
+
end
|
152
|
+
|
153
|
+
# Loop through the libraries the user added
|
154
|
+
# and run their generate methods
|
155
|
+
# which pulls in the additional optional files.
|
156
|
+
def get_libraries
|
157
|
+
libs.each do |lib|
|
158
|
+
library = QEDProject::Libraries::Base.libs[lib]
|
159
|
+
l = library.new(self)
|
160
|
+
l.generate!
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def create_asset_file
|
165
|
+
render_template_to_file("assets.yml", File.join(self.path, "config", "assets.yml"), binding)
|
166
|
+
puts "Created #{File.join(self.path, 'config', 'assets.yml')}" if self.verbose
|
167
|
+
end
|
168
|
+
|
169
|
+
def create_guardfile
|
170
|
+
render_template_to_file "Guardfile", File.join(self.path, "Guardfile"), binding
|
171
|
+
puts "Created #{ File.join(self.path, "Guardfile")}" if self.verbose
|
172
|
+
end
|
173
|
+
|
174
|
+
def create_index
|
175
|
+
@project = self
|
176
|
+
render_template_to_file "index.html", File.join(self.path, "public", "index.html"), binding
|
177
|
+
puts "Created #{ File.join(self.path, "public", "index.html")}" if self.verbose
|
178
|
+
end
|
179
|
+
|
180
|
+
def create_rakefile
|
181
|
+
render_template_to_file "Rakefile", File.join(self.path, "Rakefile"), binding
|
182
|
+
puts "Created #{ File.join(self.path, "Rakefile")}" if self.verbose
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
data/lib/qedproject.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "qedproject/version"
|
2
|
+
require "qedproject/helpers"
|
3
|
+
require "qedproject/libraries/base"
|
4
|
+
require "qedproject/libraries/jquery"
|
5
|
+
require "qedproject/libraries/backbone"
|
6
|
+
require "qedproject/libraries/knockout"
|
7
|
+
require "qedproject/libraries/jquerytmpl"
|
8
|
+
require "qedproject/libraries/skeleton"
|
9
|
+
require "qedproject/project"
|
10
|
+
|
11
|
+
module QEDProject
|
12
|
+
class BadLibraryError < RuntimeError
|
13
|
+
end
|
14
|
+
end
|
data/templates/Guardfile
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
<% if self.sass -%>
|
2
|
+
<% if self.jammit -%>
|
3
|
+
guard "sass", :input => "sass", :output => "tmp"
|
4
|
+
<% else -%>
|
5
|
+
guard "sass", :input => "sass", :output => "public/stylesheets"
|
6
|
+
<% end -%>
|
7
|
+
<% end -%>
|
8
|
+
<% if self.coffeescript -%>
|
9
|
+
<% if self.jammit -%>
|
10
|
+
guard "coffeescript", :input => "coffeescripts", :output => "tmp"
|
11
|
+
<% else -%>
|
12
|
+
guard "coffeescript", :input => "coffeescripts", :output => "public/javascripts"
|
13
|
+
<% end -%>
|
14
|
+
<% if self.testing -%>
|
15
|
+
guard "coffeescript", :input => "spec", :output => "spec"
|
16
|
+
<% end -%>
|
17
|
+
<% end -%>
|
18
|
+
<% if self.jammit -%>
|
19
|
+
guard "jammit" do
|
20
|
+
watch(/^javascripts\\/(.*)\.js/)
|
21
|
+
watch(/^stylesheets\\/(.*)\.css/)
|
22
|
+
<% if self.coffeescript -%>
|
23
|
+
watch(/^tmp\\/(.*)\\.js/)
|
24
|
+
<% end -%>
|
25
|
+
<% if self.sass -%>
|
26
|
+
watch(/^tmp\\/(.*)\\.css/)
|
27
|
+
<% end -%>
|
28
|
+
end
|
29
|
+
<% end -%>
|
data/templates/Rakefile
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
SERVER = "yourhost.com"
|
2
|
+
USERNAME = "yourusername"
|
3
|
+
REMOTE_FOLDER = "/home/#{USERNAME}/yourhost.com"
|
4
|
+
|
5
|
+
require 'net/scp'
|
6
|
+
|
7
|
+
<% if self.needs_guardfile? -%>
|
8
|
+
desc "compile CSS, js files"
|
9
|
+
task :compile do
|
10
|
+
require 'guard'
|
11
|
+
Guard.setup
|
12
|
+
Guard::Dsl.evaluate_guardfile
|
13
|
+
Guard::guards.each{|guard| guard.run_all}
|
14
|
+
end
|
15
|
+
<% end -%>
|
16
|
+
desc "Deploy web site"
|
17
|
+
<% if self.needs_guardfile? -%>
|
18
|
+
task :deploy => :compile do
|
19
|
+
<% else -%>
|
20
|
+
task :deploy do
|
21
|
+
<% end -%>
|
22
|
+
Net::SCP.start(SERVER, USERNAME, {:port => PORT} ) do |scp|
|
23
|
+
scp.upload! "public", REMOTE_FOLDER, :recursive => true
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Project</title>
|
5
|
+
<% if @project.jammit %>
|
6
|
+
<link rel="stylesheet" href="assets/app.css">
|
7
|
+
<% else -%>
|
8
|
+
<link rel="stylesheet" href="stylesheets/style.css">
|
9
|
+
<% end -%>
|
10
|
+
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
|
14
|
+
<h1>My Project</h1>
|
15
|
+
|
16
|
+
<p>
|
17
|
+
Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
|
18
|
+
eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
|
19
|
+
minim veniam, quis nostrud exercitation ullamco laboris nisi ut
|
20
|
+
aliquip ex ea commodo consequat. Duis aute irure dolor in
|
21
|
+
reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
|
22
|
+
pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
|
23
|
+
culpa qui officia deserunt mollit anim id est laborum.
|
24
|
+
</p>
|
25
|
+
|
26
|
+
|
27
|
+
<% if @project.jammit %>
|
28
|
+
<script src="assets/app.js"></script>
|
29
|
+
<% else -%>
|
30
|
+
<% @project.js_assets.each do |js| -%>
|
31
|
+
<script src="javascripts/<%=js %>"></script>
|
32
|
+
<% end -%>
|
33
|
+
<% end -%>
|
34
|
+
</body>
|
35
|
+
</html>
|
File without changes
|
@@ -0,0 +1,23 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Jasmine Test Runner</title>
|
5
|
+
<link rel="stylesheet" type="text/css" href="lib/jasmine-1.0.2/jasmine.css">
|
6
|
+
<script type="text/javascript" src="lib/jasmine-1.0.2/jasmine.js"></script>
|
7
|
+
<script type="text/javascript" src="lib/jasmine-1.0.2/jasmine-html.js"></script>
|
8
|
+
|
9
|
+
<!-- include source files here... -->
|
10
|
+
|
11
|
+
<!-- include spec files here... -->
|
12
|
+
<script type="text/javascript" src="sampleSpec.js"></script>
|
13
|
+
|
14
|
+
</head>
|
15
|
+
<body>
|
16
|
+
|
17
|
+
<script type="text/javascript">
|
18
|
+
jasmine.getEnv().addReporter(new jasmine.TrivialReporter());
|
19
|
+
jasmine.getEnv().execute();
|
20
|
+
</script>
|
21
|
+
|
22
|
+
</body>
|
23
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
0.5.3
|
@@ -0,0 +1,33 @@
|
|
1
|
+
// Backbone.js 0.5.3
|
2
|
+
// (c) 2010 Jeremy Ashkenas, DocumentCloud Inc.
|
3
|
+
// Backbone may be freely distributed under the MIT license.
|
4
|
+
// For all details and documentation:
|
5
|
+
// http://documentcloud.github.com/backbone
|
6
|
+
(function(){var h=this,p=h.Backbone,e;e=typeof exports!=="undefined"?exports:h.Backbone={};e.VERSION="0.5.3";var f=h._;if(!f&&typeof require!=="undefined")f=require("underscore")._;var g=h.jQuery||h.Zepto;e.noConflict=function(){h.Backbone=p;return this};e.emulateHTTP=!1;e.emulateJSON=!1;e.Events={bind:function(a,b,c){var d=this._callbacks||(this._callbacks={});(d[a]||(d[a]=[])).push([b,c]);return this},unbind:function(a,b){var c;if(a){if(c=this._callbacks)if(b){c=c[a];if(!c)return this;for(var d=
|
7
|
+
0,e=c.length;d<e;d++)if(c[d]&&b===c[d][0]){c[d]=null;break}}else c[a]=[]}else this._callbacks={};return this},trigger:function(a){var b,c,d,e,f=2;if(!(c=this._callbacks))return this;for(;f--;)if(b=f?a:"all",b=c[b])for(var g=0,h=b.length;g<h;g++)(d=b[g])?(e=f?Array.prototype.slice.call(arguments,1):arguments,d[0].apply(d[1]||this,e)):(b.splice(g,1),g--,h--);return this}};e.Model=function(a,b){var c;a||(a={});if(c=this.defaults)f.isFunction(c)&&(c=c.call(this)),a=f.extend({},c,a);this.attributes={};
|
8
|
+
this._escapedAttributes={};this.cid=f.uniqueId("c");this.set(a,{silent:!0});this._changed=!1;this._previousAttributes=f.clone(this.attributes);if(b&&b.collection)this.collection=b.collection;this.initialize(a,b)};f.extend(e.Model.prototype,e.Events,{_previousAttributes:null,_changed:!1,idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.attributes[a];
|
9
|
+
return this._escapedAttributes[a]=(b==null?"":""+b).replace(/&(?!\w+;|#\d+;|#x[\da-f]+;)/gi,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""").replace(/'/g,"'").replace(/\//g,"/")},has:function(a){return this.attributes[a]!=null},set:function(a,b){b||(b={});if(!a)return this;if(a.attributes)a=a.attributes;var c=this.attributes,d=this._escapedAttributes;if(!b.silent&&this.validate&&!this._performValidation(a,b))return!1;if(this.idAttribute in a)this.id=a[this.idAttribute];
|
10
|
+
var e=this._changing;this._changing=!0;for(var g in a){var h=a[g];if(!f.isEqual(c[g],h))c[g]=h,delete d[g],this._changed=!0,b.silent||this.trigger("change:"+g,this,h,b)}!e&&!b.silent&&this._changed&&this.change(b);this._changing=!1;return this},unset:function(a,b){if(!(a in this.attributes))return this;b||(b={});var c={};c[a]=void 0;if(!b.silent&&this.validate&&!this._performValidation(c,b))return!1;delete this.attributes[a];delete this._escapedAttributes[a];a==this.idAttribute&&delete this.id;this._changed=
|
11
|
+
!0;b.silent||(this.trigger("change:"+a,this,void 0,b),this.change(b));return this},clear:function(a){a||(a={});var b,c=this.attributes,d={};for(b in c)d[b]=void 0;if(!a.silent&&this.validate&&!this._performValidation(d,a))return!1;this.attributes={};this._escapedAttributes={};this._changed=!0;if(!a.silent){for(b in c)this.trigger("change:"+b,this,void 0,a);this.change(a)}return this},fetch:function(a){a||(a={});var b=this,c=a.success;a.success=function(d,e,f){if(!b.set(b.parse(d,f),a))return!1;c&&
|
12
|
+
c(b,d)};a.error=i(a.error,b,a);return(this.sync||e.sync).call(this,"read",this,a)},save:function(a,b){b||(b={});if(a&&!this.set(a,b))return!1;var c=this,d=b.success;b.success=function(a,e,f){if(!c.set(c.parse(a,f),b))return!1;d&&d(c,a,f)};b.error=i(b.error,c,b);var f=this.isNew()?"create":"update";return(this.sync||e.sync).call(this,f,this,b)},destroy:function(a){a||(a={});if(this.isNew())return this.trigger("destroy",this,this.collection,a);var b=this,c=a.success;a.success=function(d){b.trigger("destroy",
|
13
|
+
b,b.collection,a);c&&c(b,d)};a.error=i(a.error,b,a);return(this.sync||e.sync).call(this,"delete",this,a)},url:function(){var a=k(this.collection)||this.urlRoot||l();if(this.isNew())return a;return a+(a.charAt(a.length-1)=="/"?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this)},isNew:function(){return this.id==null},change:function(a){this.trigger("change",this,a);this._previousAttributes=f.clone(this.attributes);this._changed=!1},hasChanged:function(a){if(a)return this._previousAttributes[a]!=
|
14
|
+
this.attributes[a];return this._changed},changedAttributes:function(a){a||(a=this.attributes);var b=this._previousAttributes,c=!1,d;for(d in a)f.isEqual(b[d],a[d])||(c=c||{},c[d]=a[d]);return c},previous:function(a){if(!a||!this._previousAttributes)return null;return this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},_performValidation:function(a,b){var c=this.validate(a);if(c)return b.error?b.error(this,c,b):this.trigger("error",this,c,b),!1;return!0}});
|
15
|
+
e.Collection=function(a,b){b||(b={});if(b.comparator)this.comparator=b.comparator;f.bindAll(this,"_onModelEvent","_removeReference");this._reset();a&&this.reset(a,{silent:!0});this.initialize.apply(this,arguments)};f.extend(e.Collection.prototype,e.Events,{model:e.Model,initialize:function(){},toJSON:function(){return this.map(function(a){return a.toJSON()})},add:function(a,b){if(f.isArray(a))for(var c=0,d=a.length;c<d;c++)this._add(a[c],b);else this._add(a,b);return this},remove:function(a,b){if(f.isArray(a))for(var c=
|
16
|
+
0,d=a.length;c<d;c++)this._remove(a[c],b);else this._remove(a,b);return this},get:function(a){if(a==null)return null;return this._byId[a.id!=null?a.id:a]},getByCid:function(a){return a&&this._byCid[a.cid||a]},at:function(a){return this.models[a]},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");this.models=this.sortBy(this.comparator);a.silent||this.trigger("reset",this,a);return this},pluck:function(a){return f.map(this.models,function(b){return b.get(a)})},
|
17
|
+
reset:function(a,b){a||(a=[]);b||(b={});this.each(this._removeReference);this._reset();this.add(a,{silent:!0});b.silent||this.trigger("reset",this,b);return this},fetch:function(a){a||(a={});var b=this,c=a.success;a.success=function(d,f,e){b[a.add?"add":"reset"](b.parse(d,e),a);c&&c(b,d)};a.error=i(a.error,b,a);return(this.sync||e.sync).call(this,"read",this,a)},create:function(a,b){var c=this;b||(b={});a=this._prepareModel(a,b);if(!a)return!1;var d=b.success;b.success=function(a,e,f){c.add(a,b);
|
18
|
+
d&&d(a,e,f)};a.save(null,b);return a},parse:function(a){return a},chain:function(){return f(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId={};this._byCid={}},_prepareModel:function(a,b){if(a instanceof e.Model){if(!a.collection)a.collection=this}else{var c=a;a=new this.model(c,{collection:this});a.validate&&!a._performValidation(c,b)&&(a=!1)}return a},_add:function(a,b){b||(b={});a=this._prepareModel(a,b);if(!a)return!1;var c=this.getByCid(a);if(c)throw Error(["Can't add the same model to a set twice",
|
19
|
+
c.id]);this._byId[a.id]=a;this._byCid[a.cid]=a;this.models.splice(b.at!=null?b.at:this.comparator?this.sortedIndex(a,this.comparator):this.length,0,a);a.bind("all",this._onModelEvent);this.length++;b.silent||a.trigger("add",a,this,b);return a},_remove:function(a,b){b||(b={});a=this.getByCid(a)||this.get(a);if(!a)return null;delete this._byId[a.id];delete this._byCid[a.cid];this.models.splice(this.indexOf(a),1);this.length--;b.silent||a.trigger("remove",a,this,b);this._removeReference(a);return a},
|
20
|
+
_removeReference:function(a){this==a.collection&&delete a.collection;a.unbind("all",this._onModelEvent)},_onModelEvent:function(a,b,c,d){(a=="add"||a=="remove")&&c!=this||(a=="destroy"&&this._remove(b,d),b&&a==="change:"+b.idAttribute&&(delete this._byId[b.previous(b.idAttribute)],this._byId[b.id]=b),this.trigger.apply(this,arguments))}});f.each(["forEach","each","map","reduce","reduceRight","find","detect","filter","select","reject","every","all","some","any","include","contains","invoke","max",
|
21
|
+
"min","sortBy","sortedIndex","toArray","size","first","rest","last","without","indexOf","lastIndexOf","isEmpty","groupBy"],function(a){e.Collection.prototype[a]=function(){return f[a].apply(f,[this.models].concat(f.toArray(arguments)))}});e.Router=function(a){a||(a={});if(a.routes)this.routes=a.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var q=/:([\w\d]+)/g,r=/\*([\w\d]+)/g,s=/[-[\]{}()+?.,\\^$|#\s]/g;f.extend(e.Router.prototype,e.Events,{initialize:function(){},route:function(a,
|
22
|
+
b,c){e.history||(e.history=new e.History);f.isRegExp(a)||(a=this._routeToRegExp(a));e.history.route(a,f.bind(function(d){d=this._extractParameters(a,d);c.apply(this,d);this.trigger.apply(this,["route:"+b].concat(d))},this))},navigate:function(a,b){e.history.navigate(a,b)},_bindRoutes:function(){if(this.routes){var a=[],b;for(b in this.routes)a.unshift([b,this.routes[b]]);b=0;for(var c=a.length;b<c;b++)this.route(a[b][0],a[b][1],this[a[b][1]])}},_routeToRegExp:function(a){a=a.replace(s,"\\$&").replace(q,
|
23
|
+
"([^/]*)").replace(r,"(.*?)");return RegExp("^"+a+"$")},_extractParameters:function(a,b){return a.exec(b).slice(1)}});e.History=function(){this.handlers=[];f.bindAll(this,"checkUrl")};var j=/^#*/,t=/msie [\w.]+/,m=!1;f.extend(e.History.prototype,{interval:50,getFragment:function(a,b){if(a==null)if(this._hasPushState||b){a=window.location.pathname;var c=window.location.search;c&&(a+=c);a.indexOf(this.options.root)==0&&(a=a.substr(this.options.root.length))}else a=window.location.hash;return decodeURIComponent(a.replace(j,
|
24
|
+
""))},start:function(a){if(m)throw Error("Backbone.history has already been started");this.options=f.extend({},{root:"/"},this.options,a);this._wantsPushState=!!this.options.pushState;this._hasPushState=!(!this.options.pushState||!window.history||!window.history.pushState);a=this.getFragment();var b=document.documentMode;if(b=t.exec(navigator.userAgent.toLowerCase())&&(!b||b<=7))this.iframe=g('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow,this.navigate(a);
|
25
|
+
this._hasPushState?g(window).bind("popstate",this.checkUrl):"onhashchange"in window&&!b?g(window).bind("hashchange",this.checkUrl):setInterval(this.checkUrl,this.interval);this.fragment=a;m=!0;a=window.location;b=a.pathname==this.options.root;if(this._wantsPushState&&!this._hasPushState&&!b)return this.fragment=this.getFragment(null,!0),window.location.replace(this.options.root+"#"+this.fragment),!0;else if(this._wantsPushState&&this._hasPushState&&b&&a.hash)this.fragment=a.hash.replace(j,""),window.history.replaceState({},
|
26
|
+
document.title,a.protocol+"//"+a.host+this.options.root+this.fragment);if(!this.options.silent)return this.loadUrl()},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();a==this.fragment&&this.iframe&&(a=this.getFragment(this.iframe.location.hash));if(a==this.fragment||a==decodeURIComponent(this.fragment))return!1;this.iframe&&this.navigate(a);this.loadUrl()||this.loadUrl(window.location.hash)},loadUrl:function(a){var b=this.fragment=this.getFragment(a);
|
27
|
+
return f.any(this.handlers,function(a){if(a.route.test(b))return a.callback(b),!0})},navigate:function(a,b){var c=(a||"").replace(j,"");if(!(this.fragment==c||this.fragment==decodeURIComponent(c))){if(this._hasPushState){var d=window.location;c.indexOf(this.options.root)!=0&&(c=this.options.root+c);this.fragment=c;window.history.pushState({},document.title,d.protocol+"//"+d.host+c)}else if(window.location.hash=this.fragment=c,this.iframe&&c!=this.getFragment(this.iframe.location.hash))this.iframe.document.open().close(),
|
28
|
+
this.iframe.location.hash=c;b&&this.loadUrl(a)}}});e.View=function(a){this.cid=f.uniqueId("view");this._configure(a||{});this._ensureElement();this.delegateEvents();this.initialize.apply(this,arguments)};var u=/^(\S+)\s*(.*)$/,n=["model","collection","el","id","attributes","className","tagName"];f.extend(e.View.prototype,e.Events,{tagName:"div",$:function(a){return g(a,this.el)},initialize:function(){},render:function(){return this},remove:function(){g(this.el).remove();return this},make:function(a,
|
29
|
+
b,c){a=document.createElement(a);b&&g(a).attr(b);c&&g(a).html(c);return a},delegateEvents:function(a){if(a||(a=this.events))for(var b in f.isFunction(a)&&(a=a.call(this)),g(this.el).unbind(".delegateEvents"+this.cid),a){var c=this[a[b]];if(!c)throw Error('Event "'+a[b]+'" does not exist');var d=b.match(u),e=d[1];d=d[2];c=f.bind(c,this);e+=".delegateEvents"+this.cid;d===""?g(this.el).bind(e,c):g(this.el).delegate(d,e,c)}},_configure:function(a){this.options&&(a=f.extend({},this.options,a));for(var b=
|
30
|
+
0,c=n.length;b<c;b++){var d=n[b];a[d]&&(this[d]=a[d])}this.options=a},_ensureElement:function(){if(this.el){if(f.isString(this.el))this.el=g(this.el).get(0)}else{var a=this.attributes||{};if(this.id)a.id=this.id;if(this.className)a["class"]=this.className;this.el=this.make(this.tagName,a)}}});e.Model.extend=e.Collection.extend=e.Router.extend=e.View.extend=function(a,b){var c=v(this,a,b);c.extend=this.extend;return c};var w={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};e.sync=function(a,
|
31
|
+
b,c){var d=w[a];c=f.extend({type:d,dataType:"json"},c);if(!c.url)c.url=k(b)||l();if(!c.data&&b&&(a=="create"||a=="update"))c.contentType="application/json",c.data=JSON.stringify(b.toJSON());if(e.emulateJSON)c.contentType="application/x-www-form-urlencoded",c.data=c.data?{model:c.data}:{};if(e.emulateHTTP&&(d==="PUT"||d==="DELETE")){if(e.emulateJSON)c.data._method=d;c.type="POST";c.beforeSend=function(a){a.setRequestHeader("X-HTTP-Method-Override",d)}}if(c.type!=="GET"&&!e.emulateJSON)c.processData=
|
32
|
+
!1;return g.ajax(c)};var o=function(){},v=function(a,b,c){var d;d=b&&b.hasOwnProperty("constructor")?b.constructor:function(){return a.apply(this,arguments)};f.extend(d,a);o.prototype=a.prototype;d.prototype=new o;b&&f.extend(d.prototype,b);c&&f.extend(d,c);d.prototype.constructor=d;d.__super__=a.prototype;return d},k=function(a){if(!a||!a.url)return null;return f.isFunction(a.url)?a.url():a.url},l=function(){throw Error('A "url" property or function must be specified');},i=function(a,b,c){return function(d){a?
|
33
|
+
a(b,d,c):b.trigger("error",b,d,c)}}}).call(this);
|