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.
Files changed (88) hide show
  1. data/History.txt +98 -73
  2. data/Manifest.txt +2 -1
  3. data/README.txt +1 -1
  4. data/Rakefile +8 -8
  5. data/app_generators/sproutcore/USAGE +2 -3
  6. data/app_generators/sproutcore/sproutcore_generator.rb +12 -12
  7. data/app_generators/sproutcore/templates/README +26 -23
  8. data/app_generators/sproutcore/templates/{sc-config.rb → sc-config} +32 -17
  9. data/bin/sc-build +17 -17
  10. data/bin/sc-server +1 -1
  11. data/bin/sproutcore +3 -3
  12. data/clients/sc_test_runner/english.lproj/no_tests.rhtml +0 -1
  13. data/config/hoe.rb +9 -9
  14. data/config/requirements.rb +1 -1
  15. data/frameworks/sproutcore/HISTORY +14 -0
  16. data/frameworks/sproutcore/core.js +1 -1
  17. data/frameworks/sproutcore/english.lproj/theme.css +1 -0
  18. data/frameworks/sproutcore/foundation/binding.js +2 -2
  19. data/frameworks/sproutcore/foundation/timer.js +55 -22
  20. data/frameworks/sproutcore/lib/index.rhtml +2 -3
  21. data/frameworks/sproutcore/models/record.js +204 -63
  22. data/frameworks/sproutcore/tests/models/model.rhtml +360 -0
  23. data/frameworks/sproutcore/views/button/button.js +22 -1
  24. data/frameworks/sproutcore/views/collection/collection.js +6 -2
  25. data/frameworks/sproutcore/views/collection/list.js +1 -0
  26. data/frameworks/sproutcore/views/collection/source_list.js +1 -0
  27. data/frameworks/sproutcore/views/field/text_field.js +11 -2
  28. data/frameworks/sproutcore/views/inline_text_field.js +3 -2
  29. data/frameworks/sproutcore/views/menu_item.js +1 -0
  30. data/frameworks/sproutcore/views/pagination.js +1 -0
  31. data/frameworks/sproutcore/views/view.js +4 -1
  32. data/lib/sproutcore/build_tools/html_builder.rb +36 -36
  33. data/lib/sproutcore/build_tools/resource_builder.rb +55 -54
  34. data/lib/sproutcore/build_tools.rb +12 -12
  35. data/lib/sproutcore/bundle.rb +162 -164
  36. data/lib/sproutcore/bundle_manifest.rb +154 -107
  37. data/lib/sproutcore/generator_helper.rb +23 -23
  38. data/lib/sproutcore/helpers/capture_helper.rb +10 -10
  39. data/lib/sproutcore/helpers/static_helper.rb +39 -26
  40. data/lib/sproutcore/helpers/tag_helper.rb +10 -10
  41. data/lib/sproutcore/helpers/text_helper.rb +36 -36
  42. data/lib/sproutcore/helpers.rb +1 -1
  43. data/lib/sproutcore/jsdoc.rb +10 -10
  44. data/lib/sproutcore/jsmin.rb +14 -14
  45. data/lib/sproutcore/library.rb +135 -87
  46. data/lib/sproutcore/merb/bundle_controller.rb +77 -54
  47. data/lib/sproutcore/merb/router.rb +19 -12
  48. data/lib/sproutcore/merb.rb +1 -1
  49. data/lib/sproutcore/version.rb +1 -1
  50. data/lib/sproutcore/view_helpers.rb +121 -121
  51. data/lib/sproutcore.rb +5 -7
  52. data/sc-config.rb +6 -0
  53. data/sc_generators/client/README +1 -1
  54. data/sc_generators/client/USAGE +1 -2
  55. data/sc_generators/client/client_generator.rb +6 -6
  56. data/sc_generators/client/templates/core.js +2 -2
  57. data/sc_generators/client/templates/english.lproj/body.css +79 -81
  58. data/sc_generators/client/templates/english.lproj/strings.js +1 -2
  59. data/sc_generators/client/templates/main.js +6 -8
  60. data/sc_generators/controller/USAGE +1 -2
  61. data/sc_generators/controller/controller_generator.rb +7 -7
  62. data/sc_generators/controller/templates/controller.js +3 -3
  63. data/sc_generators/controller/templates/test.rhtml +1 -1
  64. data/sc_generators/framework/README +1 -2
  65. data/sc_generators/framework/USAGE +2 -3
  66. data/sc_generators/framework/framework_generator.rb +5 -5
  67. data/sc_generators/framework/templates/core.js +3 -3
  68. data/sc_generators/framework/templates/english.lproj/strings.js +1 -2
  69. data/sc_generators/language/USAGE +1 -2
  70. data/sc_generators/language/language_generator.rb +6 -6
  71. data/sc_generators/language/templates/strings.js +1 -2
  72. data/sc_generators/model/USAGE +1 -2
  73. data/sc_generators/model/model_generator.rb +7 -7
  74. data/sc_generators/model/templates/fixture.js +26 -26
  75. data/sc_generators/model/templates/model.js +5 -5
  76. data/sc_generators/model/templates/test.rhtml +2 -2
  77. data/sc_generators/test/USAGE +1 -2
  78. data/sc_generators/test/templates/test.rhtml +2 -2
  79. data/sc_generators/test/test_generator.rb +6 -6
  80. data/sc_generators/view/USAGE +1 -2
  81. data/sc_generators/view/templates/test.rhtml +2 -2
  82. data/sc_generators/view/templates/view.js +3 -3
  83. data/sc_generators/view/view_generator.rb +7 -7
  84. data/spec/spec.opts +1 -1
  85. data/spec/spec_helper.rb +1 -1
  86. data/spec/sproutcore_spec.rb +3 -3
  87. data/tasks/deployment.rake +4 -4
  88. 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 location it is
9
- # mounted at. For index.html requests, it will rebuild the html file everytime it is
10
- # requested if you are in development mode. For all other requests, it will build the
11
- # resource one time and then return the file if it already exists.
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. Example
23
- # the request path to determine which bundle should handle the request.
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.path
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
- response = http.send(http_method, http_path, headers)
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 matching
8
- # this path root will by default be handled by this new controller.
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. This
12
- # will be passed through to the router, so you can use anything you like.
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
@@ -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.)
@@ -2,7 +2,7 @@ module SproutCore #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 9
5
- TINY = 11
5
+ TINY = 12
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end