sproutcore 0.9.11 → 0.9.12
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/History.txt +98 -73
- data/Manifest.txt +2 -1
- data/README.txt +1 -1
- data/Rakefile +8 -8
- data/app_generators/sproutcore/USAGE +2 -3
- data/app_generators/sproutcore/sproutcore_generator.rb +12 -12
- data/app_generators/sproutcore/templates/README +26 -23
- data/app_generators/sproutcore/templates/{sc-config.rb → sc-config} +32 -17
- data/bin/sc-build +17 -17
- data/bin/sc-server +1 -1
- data/bin/sproutcore +3 -3
- data/clients/sc_test_runner/english.lproj/no_tests.rhtml +0 -1
- data/config/hoe.rb +9 -9
- data/config/requirements.rb +1 -1
- data/frameworks/sproutcore/HISTORY +14 -0
- data/frameworks/sproutcore/core.js +1 -1
- data/frameworks/sproutcore/english.lproj/theme.css +1 -0
- data/frameworks/sproutcore/foundation/binding.js +2 -2
- data/frameworks/sproutcore/foundation/timer.js +55 -22
- data/frameworks/sproutcore/lib/index.rhtml +2 -3
- data/frameworks/sproutcore/models/record.js +204 -63
- data/frameworks/sproutcore/tests/models/model.rhtml +360 -0
- data/frameworks/sproutcore/views/button/button.js +22 -1
- data/frameworks/sproutcore/views/collection/collection.js +6 -2
- data/frameworks/sproutcore/views/collection/list.js +1 -0
- data/frameworks/sproutcore/views/collection/source_list.js +1 -0
- data/frameworks/sproutcore/views/field/text_field.js +11 -2
- data/frameworks/sproutcore/views/inline_text_field.js +3 -2
- data/frameworks/sproutcore/views/menu_item.js +1 -0
- data/frameworks/sproutcore/views/pagination.js +1 -0
- data/frameworks/sproutcore/views/view.js +4 -1
- data/lib/sproutcore/build_tools/html_builder.rb +36 -36
- data/lib/sproutcore/build_tools/resource_builder.rb +55 -54
- data/lib/sproutcore/build_tools.rb +12 -12
- data/lib/sproutcore/bundle.rb +162 -164
- data/lib/sproutcore/bundle_manifest.rb +154 -107
- data/lib/sproutcore/generator_helper.rb +23 -23
- data/lib/sproutcore/helpers/capture_helper.rb +10 -10
- data/lib/sproutcore/helpers/static_helper.rb +39 -26
- data/lib/sproutcore/helpers/tag_helper.rb +10 -10
- data/lib/sproutcore/helpers/text_helper.rb +36 -36
- data/lib/sproutcore/helpers.rb +1 -1
- data/lib/sproutcore/jsdoc.rb +10 -10
- data/lib/sproutcore/jsmin.rb +14 -14
- data/lib/sproutcore/library.rb +135 -87
- data/lib/sproutcore/merb/bundle_controller.rb +77 -54
- data/lib/sproutcore/merb/router.rb +19 -12
- data/lib/sproutcore/merb.rb +1 -1
- data/lib/sproutcore/version.rb +1 -1
- data/lib/sproutcore/view_helpers.rb +121 -121
- data/lib/sproutcore.rb +5 -7
- data/sc-config.rb +6 -0
- data/sc_generators/client/README +1 -1
- data/sc_generators/client/USAGE +1 -2
- data/sc_generators/client/client_generator.rb +6 -6
- data/sc_generators/client/templates/core.js +2 -2
- data/sc_generators/client/templates/english.lproj/body.css +79 -81
- data/sc_generators/client/templates/english.lproj/strings.js +1 -2
- data/sc_generators/client/templates/main.js +6 -8
- data/sc_generators/controller/USAGE +1 -2
- data/sc_generators/controller/controller_generator.rb +7 -7
- data/sc_generators/controller/templates/controller.js +3 -3
- data/sc_generators/controller/templates/test.rhtml +1 -1
- data/sc_generators/framework/README +1 -2
- data/sc_generators/framework/USAGE +2 -3
- data/sc_generators/framework/framework_generator.rb +5 -5
- data/sc_generators/framework/templates/core.js +3 -3
- data/sc_generators/framework/templates/english.lproj/strings.js +1 -2
- data/sc_generators/language/USAGE +1 -2
- data/sc_generators/language/language_generator.rb +6 -6
- data/sc_generators/language/templates/strings.js +1 -2
- data/sc_generators/model/USAGE +1 -2
- data/sc_generators/model/model_generator.rb +7 -7
- data/sc_generators/model/templates/fixture.js +26 -26
- data/sc_generators/model/templates/model.js +5 -5
- data/sc_generators/model/templates/test.rhtml +2 -2
- data/sc_generators/test/USAGE +1 -2
- data/sc_generators/test/templates/test.rhtml +2 -2
- data/sc_generators/test/test_generator.rb +6 -6
- data/sc_generators/view/USAGE +1 -2
- data/sc_generators/view/templates/test.rhtml +2 -2
- data/sc_generators/view/templates/view.js +3 -3
- data/sc_generators/view/view_generator.rb +7 -7
- data/spec/spec.opts +1 -1
- data/spec/spec_helper.rb +1 -1
- data/spec/sproutcore_spec.rb +3 -3
- data/tasks/deployment.rake +4 -4
- metadata +4 -3
|
@@ -3,28 +3,33 @@ require 'net/http'
|
|
|
3
3
|
require 'uri'
|
|
4
4
|
|
|
5
5
|
module SproutCore
|
|
6
|
+
|
|
7
|
+
NO_BODY_METHOD = [:delete, :get, :copy, :head, :move, :options, :trace]
|
|
8
|
+
|
|
6
9
|
module Merb
|
|
7
|
-
|
|
8
|
-
# A subclass of this controller handles all incoming requests for the
|
|
9
|
-
# mounted at. For index.html requests, it will rebuild the
|
|
10
|
-
# requested if you are in development mode. For
|
|
11
|
-
# resource one time and then return
|
|
10
|
+
|
|
11
|
+
# A subclass of this controller handles all incoming requests for the
|
|
12
|
+
# location it is mounted at. For index.html requests, it will rebuild the
|
|
13
|
+
# html file everytime it is requested if you are in development mode. For
|
|
14
|
+
# all other requests, it will build the resource one time and then return
|
|
15
|
+
# the file if it already exists.
|
|
12
16
|
class BundleController < ::Merb::Controller
|
|
13
|
-
|
|
17
|
+
|
|
14
18
|
def self.library_for_class(klass)
|
|
15
19
|
(@registered_libraries ||= {})[klass]
|
|
16
20
|
end
|
|
17
|
-
|
|
21
|
+
|
|
18
22
|
def self.register_library_for_class(library, klass)
|
|
19
23
|
(@registered_libraries ||= {})[klass] = library
|
|
20
24
|
end
|
|
21
|
-
|
|
22
|
-
# Entry point for all requests routed through the SproutCore controller.
|
|
23
|
-
# the request path to determine which bundle should handle the
|
|
25
|
+
|
|
26
|
+
# Entry point for all requests routed through the SproutCore controller.
|
|
27
|
+
# Example the request path to determine which bundle should handle the
|
|
28
|
+
# request.
|
|
24
29
|
def main
|
|
25
30
|
|
|
26
|
-
# Before we do anything, set the build_mode for the bundles. This
|
|
27
|
-
# shouldn't change during execution, but if we set this during the
|
|
31
|
+
# Before we do anything, set the build_mode for the bundles. This
|
|
32
|
+
# shouldn't change during execution, but if we set this during the
|
|
28
33
|
# router call, the Merb.environment is sometimes not ready yet.
|
|
29
34
|
#
|
|
30
35
|
if ::Merb.environment.to_sym == :production
|
|
@@ -32,23 +37,23 @@ module SproutCore
|
|
|
32
37
|
else
|
|
33
38
|
::SproutCore.logger.level = Logger::DEBUG
|
|
34
39
|
end
|
|
35
|
-
|
|
40
|
+
|
|
36
41
|
# Make sure we can service this with a bundle
|
|
37
42
|
# If no bundle is found, try to proxy...
|
|
38
43
|
if current_bundle.nil?
|
|
39
44
|
# if proxy url, return proxy...
|
|
40
|
-
url = request.
|
|
41
|
-
proxy_url, proxy_opts = library.proxy_url_for(url)
|
|
42
|
-
if proxy_url
|
|
45
|
+
url = request.uri
|
|
46
|
+
proxy_url, proxy_opts = library.proxy_url_for(url)
|
|
47
|
+
if proxy_url
|
|
43
48
|
return handle_proxy(url, proxy_url, proxy_opts)
|
|
44
49
|
else
|
|
45
|
-
raise(NotFound, "No SproutCore Bundle registered at this location.")
|
|
50
|
+
raise(NotFound, "No SproutCore Bundle registered at this location.")
|
|
46
51
|
end
|
|
47
52
|
end
|
|
48
53
|
|
|
49
54
|
# Check for a few special urls that need to be rewritten
|
|
50
55
|
url = request.path
|
|
51
|
-
if request.method == :get
|
|
56
|
+
if request.method == :get
|
|
52
57
|
url = rewrite_bundle_if(url, /^#{current_bundle.index_root}\/-tests/, :sc_test_runner)
|
|
53
58
|
url = rewrite_bundle_if(url, /^#{current_bundle.index_root}\/-docs/, :sc_docs)
|
|
54
59
|
end
|
|
@@ -72,31 +77,31 @@ module SproutCore
|
|
|
72
77
|
else
|
|
73
78
|
ret = handle_resource(url)
|
|
74
79
|
end
|
|
75
|
-
|
|
80
|
+
|
|
76
81
|
# Done!
|
|
77
82
|
return ret
|
|
78
83
|
end
|
|
79
|
-
|
|
84
|
+
|
|
80
85
|
# Invoked whenever you request a regular resource
|
|
81
86
|
def handle_resource(url)
|
|
82
|
-
|
|
83
|
-
# Get the entry for the resource.
|
|
87
|
+
|
|
88
|
+
# Get the entry for the resource.
|
|
84
89
|
entry = current_bundle.entry_for_url(url, :hidden => :include)
|
|
85
90
|
raise(NotFound, "No matching entry in #{current_bundle.bundle_name} for #{url}") if entry.nil?
|
|
86
|
-
|
|
91
|
+
|
|
87
92
|
build_path = entry.build_path
|
|
88
93
|
|
|
89
|
-
# Found an entry, build the resource. If the resource has already
|
|
90
|
-
# been built, this will not do much. If this the resource is an
|
|
94
|
+
# Found an entry, build the resource. If the resource has already
|
|
95
|
+
# been built, this will not do much. If this the resource is an
|
|
91
96
|
# index.html file, force the build.
|
|
92
97
|
is_index = /\/index\.html$/ =~ url
|
|
93
98
|
|
|
94
|
-
# If we need to serve the source directly, then just set the
|
|
99
|
+
# If we need to serve the source directly, then just set the
|
|
95
100
|
# build path to the source_path.
|
|
96
101
|
if entry.use_source_directly?
|
|
97
102
|
build_path = entry.source_path
|
|
98
|
-
|
|
99
|
-
# Otherwise, run the build command on the entry to make sure the
|
|
103
|
+
|
|
104
|
+
# Otherwise, run the build command on the entry to make sure the
|
|
100
105
|
# file is up to date.
|
|
101
106
|
else
|
|
102
107
|
current_bundle.build_entry(entry, :force => is_index, :hidden => :include)
|
|
@@ -110,33 +115,33 @@ module SproutCore
|
|
|
110
115
|
# And return the file. Set the content type using a mime-map borroed from Rack.
|
|
111
116
|
headers['Content-Type'] = entry.content_type
|
|
112
117
|
headers['Content-Length'] = File.size(build_path).to_s
|
|
113
|
-
ret = File.open(build_path)
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
# In development mode only, immediately delete built composite
|
|
118
|
+
ret = File.open(build_path, 'rb')
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
# In development mode only, immediately delete built composite
|
|
117
122
|
# resources. We want each request to come directly to us.
|
|
118
123
|
if (current_bundle.build_mode == :development) && (!entry.cacheable?)
|
|
119
|
-
|
|
124
|
+
|
|
120
125
|
# Deleting composite resources will not work in windows because it
|
|
121
126
|
# does not like to have files you just open deleted. (Its OK on
|
|
122
127
|
# windows)
|
|
123
128
|
FileUtils.rm(build_path) if (RUBY_PLATFORM !~ /mswin32/)
|
|
124
129
|
end
|
|
125
|
-
|
|
130
|
+
|
|
126
131
|
return ret
|
|
127
132
|
end
|
|
128
133
|
|
|
129
134
|
# Proxy the request and return the result...
|
|
130
|
-
def handle_proxy(url, proxy_url, opts ={})
|
|
131
|
-
|
|
135
|
+
def handle_proxy(url, proxy_url, opts ={})
|
|
136
|
+
|
|
132
137
|
# collect the method
|
|
133
138
|
http_method = request.method
|
|
134
139
|
|
|
135
140
|
# capture the origin host for cookies. strip away any port.
|
|
136
141
|
origin_host = request.host.gsub(/:[0-9]+$/,'')
|
|
137
|
-
|
|
142
|
+
|
|
138
143
|
# collect the headers...
|
|
139
|
-
headers = {}
|
|
144
|
+
headers = {}
|
|
140
145
|
request.env.each do |key, value|
|
|
141
146
|
next unless key =~ /^HTTP_/
|
|
142
147
|
key = key.gsub(/^HTTP_/,'').titleize.gsub(' ','-')
|
|
@@ -151,12 +156,22 @@ module SproutCore
|
|
|
151
156
|
|
|
152
157
|
# now make the request...
|
|
153
158
|
response = nil
|
|
159
|
+
|
|
160
|
+
# Handle those that require a body.
|
|
161
|
+
|
|
154
162
|
::Net::HTTP.start(http_host, http_port) do |http|
|
|
155
|
-
|
|
163
|
+
if NO_BODY_METHOD.include?(http_method.to_sym)
|
|
164
|
+
response = http.send(http_method, http_path, headers)
|
|
165
|
+
else
|
|
166
|
+
http_body = request.raw_post
|
|
167
|
+
response = http.send(http_method, http_path, http_body, headers)
|
|
168
|
+
end
|
|
156
169
|
end
|
|
157
170
|
|
|
158
171
|
# Now set the status, headers, and body.
|
|
159
172
|
@status = response.code
|
|
173
|
+
|
|
174
|
+
SC.logger.debug " ~ PROXY: #{@status} #{request.uri} -> http://#{http_host}:#{http_port}#{http_path}"
|
|
160
175
|
|
|
161
176
|
# Transfer response headers into reponse
|
|
162
177
|
ignore = ['transfer-encoding', 'keep-alive', 'connection']
|
|
@@ -169,21 +184,29 @@ module SproutCore
|
|
|
169
184
|
if key.downcase == 'set-cookie'
|
|
170
185
|
value.gsub!(/domain=[^\;]+\;? ?/,'')
|
|
171
186
|
end
|
|
172
|
-
|
|
187
|
+
|
|
188
|
+
# Location headers should rewrite the hostname if it is included.
|
|
189
|
+
if key.downcase == 'location'
|
|
190
|
+
value.gsub!(/^http:\/\/#{http_host}(:[0-9]+)?\//, "http://#{request.host}/")
|
|
191
|
+
end
|
|
192
|
+
|
|
173
193
|
# Prep key and set header.
|
|
174
194
|
key = key.split('-').map { |x| x.downcase.capitalize }.join('-')
|
|
195
|
+
SC.logger.debug " #{key}: #{value}"
|
|
175
196
|
@headers[key] = value
|
|
176
197
|
end
|
|
177
|
-
|
|
198
|
+
|
|
199
|
+
SC.logger.debug ''
|
|
200
|
+
|
|
178
201
|
# Transfer response body
|
|
179
202
|
return response.body
|
|
180
203
|
end
|
|
181
|
-
|
|
204
|
+
|
|
182
205
|
# Returns JSON containing all of the tests
|
|
183
206
|
def handle_test(url)
|
|
184
207
|
test_entries = current_bundle.entries_for(:test, :hidden => :include)
|
|
185
208
|
content_type = :json
|
|
186
|
-
ret = test_entries.map do |entry|
|
|
209
|
+
ret = test_entries.map do |entry|
|
|
187
210
|
{ :name => entry.filename.gsub(/^tests\//,''), :url => "#{entry.url}?#{entry.timestamp}" }
|
|
188
211
|
end
|
|
189
212
|
return ret.to_json
|
|
@@ -194,22 +217,22 @@ module SproutCore
|
|
|
194
217
|
JSDoc.generate :bundle => current_bundle
|
|
195
218
|
return "OK"
|
|
196
219
|
end
|
|
197
|
-
|
|
220
|
+
|
|
198
221
|
######################################################################
|
|
199
222
|
## Support Methods
|
|
200
223
|
##
|
|
201
|
-
|
|
224
|
+
|
|
202
225
|
# Returns the library for this class
|
|
203
226
|
def library
|
|
204
227
|
::SproutCore::Merb::BundleController.library_for_class(self.class)
|
|
205
228
|
end
|
|
206
|
-
|
|
207
|
-
|
|
229
|
+
|
|
230
|
+
|
|
208
231
|
# Returns the bundle for this request
|
|
209
232
|
def current_bundle
|
|
210
233
|
return @current_bundle unless @current_bundle.nil?
|
|
211
234
|
|
|
212
|
-
# Tear down the URL, looking for the first bundle
|
|
235
|
+
# Tear down the URL, looking for the first bundle
|
|
213
236
|
bundle_map = library.bundles_grouped_by_url
|
|
214
237
|
url = request.path.split('/')
|
|
215
238
|
ret = nil
|
|
@@ -217,15 +240,15 @@ module SproutCore
|
|
|
217
240
|
ret = bundle_map[url.join('/')]
|
|
218
241
|
url.pop
|
|
219
242
|
end
|
|
220
|
-
|
|
243
|
+
|
|
221
244
|
# Try root path if nothing found
|
|
222
245
|
ret = bundle_map['/'] if ret.nil?
|
|
223
|
-
|
|
246
|
+
|
|
224
247
|
# Return
|
|
225
248
|
return (@current_bundle = ret)
|
|
226
249
|
end
|
|
227
250
|
|
|
228
|
-
# This method is used to redirect certain urls to an alternate bundle. If the
|
|
251
|
+
# This method is used to redirect certain urls to an alternate bundle. If the
|
|
229
252
|
# match phrase matches the url, then both the url we use to fetch resources and the
|
|
230
253
|
# current_bundle will be swapped out.
|
|
231
254
|
#
|
|
@@ -246,8 +269,8 @@ module SproutCore
|
|
|
246
269
|
end
|
|
247
270
|
return url
|
|
248
271
|
end
|
|
249
|
-
|
|
272
|
+
|
|
250
273
|
end
|
|
251
|
-
|
|
274
|
+
|
|
252
275
|
end
|
|
253
|
-
end
|
|
276
|
+
end
|
|
@@ -3,37 +3,44 @@ require 'sproutcore/merb/bundle_controller'
|
|
|
3
3
|
module SproutCore
|
|
4
4
|
module Merb
|
|
5
5
|
module RouterMethods
|
|
6
|
-
|
|
7
|
-
# Connect a BundleController to the specified location. All requests
|
|
8
|
-
# this path root will by default be handled by this new
|
|
6
|
+
|
|
7
|
+
# Connect a BundleController to the specified location. All requests
|
|
8
|
+
# matching this path root will by default be handled by this new
|
|
9
|
+
# controller.
|
|
9
10
|
#
|
|
10
11
|
# ==== Params
|
|
11
|
-
# path<String>:: The root path or other matcher to use for the matcher.
|
|
12
|
-
# will be passed through to the router, so you can use anything
|
|
12
|
+
# path<String>:: The root path or other matcher to use for the matcher.
|
|
13
|
+
# This will be passed through to the router, so you can use anything
|
|
14
|
+
# you like.
|
|
13
15
|
#
|
|
14
16
|
# === Options
|
|
15
|
-
# library:: Optional path to the library that should be hosted
|
|
17
|
+
# library:: Optional path to the library that should be hosted
|
|
16
18
|
# You can also include any other options that are known to Merb::Bundle
|
|
17
19
|
#
|
|
18
20
|
def connect_clients(match_path, opts ={}, &block)
|
|
19
|
-
|
|
20
|
-
# Create library
|
|
21
|
+
|
|
22
|
+
# Create library
|
|
21
23
|
library_root = opts.delete(:library) || opts.delete(:library_root) || ::Merb.root
|
|
22
24
|
library = Library.library_for(library_root, opts)
|
|
23
|
-
|
|
25
|
+
if library.nil?
|
|
26
|
+
raise "ERROR: No sc-config found at #{library_root}. Make sure you start sc-server in a directory with an sc-config file."
|
|
27
|
+
else
|
|
28
|
+
SC.logger.debug "Loading SproutCore bundles in #{library.root_path}"
|
|
29
|
+
end
|
|
30
|
+
|
|
24
31
|
# Define new subclass of bundle controller
|
|
25
32
|
cnt = 0
|
|
26
33
|
while Object.const_defined?(class_name = "SproutCoreBundleController#{cnt}".to_sym)
|
|
27
34
|
cnt += 1
|
|
28
35
|
end
|
|
29
36
|
klass = eval("class ::#{class_name} < SproutCore::Merb::BundleController; end; #{class_name}")
|
|
30
|
-
|
|
37
|
+
|
|
31
38
|
# Register library for class in BundleController
|
|
32
39
|
::SproutCore::Merb::BundleController.register_library_for_class(library, klass)
|
|
33
|
-
|
|
40
|
+
|
|
34
41
|
# Finally, register match
|
|
35
42
|
return self.match(%r[^#{match_path}\/?.*]).to(:controller => "sprout_core_bundle_controller_#{cnt}", :action => 'main')
|
|
36
|
-
|
|
43
|
+
|
|
37
44
|
end
|
|
38
45
|
end
|
|
39
46
|
end
|
data/lib/sproutcore/merb.rb
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
#
|
|
8
8
|
# The first parameter you pass is the URL you want SproutCore apps to be served from. Anything
|
|
9
9
|
# URL beginning with this root will be automatically directed to the SproutCore build tools.
|
|
10
|
-
#
|
|
10
|
+
#
|
|
11
11
|
# The second parameter is an optional root path to the Library that you want hosted at that
|
|
12
12
|
# location. If you do not pass this parameter then Merb.root will be used (which is what you
|
|
13
13
|
# usually want anyway.)
|