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
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
require 'yaml'
|
|
2
2
|
|
|
3
3
|
module SproutCore
|
|
4
|
-
|
|
5
|
-
# A Bundle Manifest describes all of the resources in a bundle, including
|
|
4
|
+
|
|
5
|
+
# A Bundle Manifest describes all of the resources in a bundle, including
|
|
6
6
|
# mapping their source paths, destination paths, and urls.
|
|
7
7
|
#
|
|
8
|
-
# A Bundle will create a manifest for every language you request from it.
|
|
9
|
-
# If you invoke reload! on the bundle, it will dispose of its manifests and
|
|
8
|
+
# A Bundle will create a manifest for every language you request from it.
|
|
9
|
+
# If you invoke reload! on the bundle, it will dispose of its manifests and
|
|
10
10
|
# rebuild them.
|
|
11
11
|
#
|
|
12
12
|
class BundleManifest
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
CACHED_TYPES = [:javascript, :stylesheet, :fixture, :test]
|
|
15
15
|
SYMLINKED_TYPES = [:resource]
|
|
16
|
-
|
|
16
|
+
|
|
17
17
|
attr_reader :bundle, :language, :build_mode
|
|
18
|
-
|
|
18
|
+
|
|
19
19
|
def initialize(bundle, language, build_mode)
|
|
20
20
|
@bundle = bundle
|
|
21
21
|
@language = language
|
|
@@ -48,95 +48,122 @@ module SproutCore
|
|
|
48
48
|
def to_hash; @entries_by_type; end
|
|
49
49
|
def to_s; @entries_by_filename.to_yaml; end
|
|
50
50
|
|
|
51
|
-
|
|
51
|
+
# ==== Returns
|
|
52
|
+
# true if javascripts should be combined
|
|
53
|
+
def combine_javascript?
|
|
54
|
+
bundle.library.combine_javascript_build_modes.include?(build_mode)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# ==== Returns
|
|
58
|
+
# true if stylesheets should be combined
|
|
59
|
+
def combine_stylesheets?
|
|
60
|
+
bundle.library.combine_stylesheets_build_modes.include?(build_mode)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# ==== Returns
|
|
64
|
+
# true if stylesheets should be combined
|
|
65
|
+
def include_fixtures?
|
|
66
|
+
bundle.library.include_fixtures_build_modes.include?(build_mode)
|
|
67
|
+
end
|
|
52
68
|
|
|
69
|
+
protected
|
|
70
|
+
|
|
53
71
|
# Builds a manifest for the bundle and the specified language
|
|
54
72
|
def build!
|
|
55
|
-
|
|
56
|
-
# STEP 1: Catalog all of the files in the project, including the target
|
|
57
|
-
# language and the default language. This will filter out resources not
|
|
73
|
+
|
|
74
|
+
# STEP 1: Catalog all of the files in the project, including the target
|
|
75
|
+
# language and the default language. This will filter out resources not
|
|
58
76
|
# used in this language.
|
|
59
77
|
entries = catalog_entries
|
|
60
|
-
|
|
61
|
-
# STEP 2: Combine the HTML file paths into a single entry, unless this
|
|
78
|
+
|
|
79
|
+
# STEP 2: Combine the HTML file paths into a single entry, unless this
|
|
62
80
|
# is a framework
|
|
63
81
|
working = entries[:html] ||= []
|
|
64
|
-
|
|
82
|
+
|
|
65
83
|
if bundle.can_have_html?
|
|
66
84
|
working << build_entry_for('index.html', :html, working)
|
|
67
85
|
else
|
|
68
86
|
working.each { |x| x.hidden = true }
|
|
69
87
|
end
|
|
70
|
-
|
|
71
|
-
# STEP
|
|
72
|
-
|
|
73
|
-
|
|
88
|
+
|
|
89
|
+
# STEP 5: Add entry for javascript.js & stylesheet.js. If in production
|
|
90
|
+
# mode, set these to visible and hide the composite. If in dev mode, do
|
|
91
|
+
# the opposite.
|
|
92
|
+
|
|
93
|
+
# STEP 3: Handle special build modes...
|
|
94
|
+
|
|
74
95
|
# a. Merge fixture types into JS types & tests
|
|
75
|
-
|
|
76
|
-
entries[:javascript] = (entries[:javascript] || []) + entries[:fixture]
|
|
96
|
+
if self.include_fixtures? && !entries[:fixture].nil?
|
|
97
|
+
entries[:javascript] = (entries[:javascript] || []) + entries[:fixture]
|
|
98
|
+
else
|
|
99
|
+
entries.delete(:fixture)
|
|
77
100
|
end
|
|
78
|
-
|
|
79
|
-
# b. Rewrite all of the JS & CSS file paths and URLs to point to
|
|
80
|
-
# cached versions
|
|
101
|
+
|
|
102
|
+
# b. Rewrite all of the JS & CSS file paths and URLs to point to
|
|
103
|
+
# cached versions
|
|
81
104
|
# (Cached versions are written to _cache/filename-ctime.ext)
|
|
82
|
-
|
|
83
|
-
|
|
105
|
+
if self.build_mode == :development
|
|
106
|
+
(entries[:javascript] ||= []).each do | entry |
|
|
107
|
+
setup_timestamp_token(entry)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
(entries[:stylesheet] ||= []).each do | entry |
|
|
111
|
+
setup_timestamp_token(entry)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
# c. Rewrite the URLs for all other resources to go through the _src
|
|
115
|
+
# symlink
|
|
116
|
+
## -----> Already done build_entry_for()
|
|
117
|
+
# a. Combine the JS file paths into a single entry for the
|
|
118
|
+
# javascript.js
|
|
119
|
+
hide_composite = self.combine_javascript?
|
|
120
|
+
if (working = entries[:javascript]) && working.size>0
|
|
121
|
+
entry = build_entry_for('javascript.js', :javascript, working, hide_composite)
|
|
122
|
+
setup_timestamp_token(entry) if self.build_mode == :development
|
|
123
|
+
entry.hidden = true unless hide_composite
|
|
124
|
+
working << entry
|
|
84
125
|
end
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
126
|
+
|
|
127
|
+
# b. Combine the CSS file paths into a single entry for the
|
|
128
|
+
# stylesheet.css
|
|
129
|
+
hide_composite = self.combine_stylesheets?
|
|
130
|
+
if (working = entries[:stylesheet]) && working.size>0
|
|
131
|
+
entry = build_entry_for('stylesheet.css', :stylesheet, working, hide_composite)
|
|
132
|
+
setup_timestamp_token(entry) if self.build_mode == :development
|
|
133
|
+
entry.hidden = true unless hide_composite
|
|
134
|
+
working << entry
|
|
88
135
|
end
|
|
89
|
-
|
|
90
|
-
# c. Rewrite the URLs for all other resources to go through the _src symlink
|
|
91
|
-
##-----> Already done build_entry_for()
|
|
92
136
|
|
|
93
137
|
|
|
94
|
-
|
|
138
|
+
|
|
139
|
+
# c. Remove the entries for anything that is not JS, CSS, HTML or
|
|
140
|
+
# Resource
|
|
95
141
|
else
|
|
96
|
-
|
|
97
|
-
# c. Remove the entries for anything that is not JS, CSS, HTML or Resource
|
|
98
|
-
entries.delete(:fixture)
|
|
99
142
|
entries.delete(:test)
|
|
100
143
|
end
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
#
|
|
104
|
-
|
|
105
|
-
hide_composite = (self.build_mode != :development)
|
|
106
|
-
|
|
107
|
-
# a. Combine the JS file paths into a single entry for the javascript.js
|
|
108
|
-
if (working = entries[:javascript]) && working.size>0
|
|
109
|
-
entry = build_entry_for('javascript.js', :javascript, working, hide_composite)
|
|
110
|
-
entry.hidden = true unless hide_composite
|
|
111
|
-
working << entry
|
|
112
|
-
end
|
|
113
|
-
|
|
114
|
-
# b. Combine the CSS file paths into a single entry for the stylesheet.css
|
|
115
|
-
if (working = entries[:stylesheet]) && working.size>0
|
|
116
|
-
entry = build_entry_for('stylesheet.css', :stylesheet, working, hide_composite)
|
|
117
|
-
entry.hidden = true unless hide_composite
|
|
118
|
-
working << entry
|
|
119
|
-
end
|
|
120
|
-
|
|
121
|
-
# Save entries into hashes
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
# Save entries into hashes
|
|
122
147
|
@entries_by_type = entries
|
|
123
148
|
@entries_by_filenames = {}
|
|
124
|
-
entries.values.flatten.each
|
|
149
|
+
entries.values.flatten.each do |entry|
|
|
150
|
+
@entries_by_filename[entry.filename] = entry
|
|
151
|
+
end
|
|
125
152
|
end
|
|
126
|
-
|
|
127
|
-
# Build a catalog of entries for this manifest. This will simply filter
|
|
128
|
-
# that don't actually belong in the current language
|
|
153
|
+
|
|
154
|
+
# Build a catalog of entries for this manifest. This will simply filter
|
|
155
|
+
# out the files that don't actually belong in the current language
|
|
129
156
|
def catalog_entries
|
|
130
157
|
|
|
131
158
|
# Entries arranged by resource filename
|
|
132
159
|
entries = {}
|
|
133
160
|
default_lproj_entries = {}
|
|
134
161
|
target_lproj_entries = {}
|
|
135
|
-
|
|
162
|
+
|
|
136
163
|
# Get the name of the lproj dirs for the default and current languages
|
|
137
164
|
default_lproj = bundle.lproj_for(bundle.preferred_language)
|
|
138
165
|
target_lproj = bundle.lproj_for(language)
|
|
139
|
-
|
|
166
|
+
|
|
140
167
|
# Any files living in the two lproj dirs will be shunted off into these arrays
|
|
141
168
|
# and processed later to make sure we process them in the right order
|
|
142
169
|
default_lproj_files = []
|
|
@@ -145,15 +172,15 @@ module SproutCore
|
|
|
145
172
|
# Now, glob all the files and sort through them
|
|
146
173
|
old_wd = Dir.getwd; Dir.chdir(bundle.source_root)
|
|
147
174
|
Dir.glob(File.join('**','*')).each do | src_path |
|
|
148
|
-
|
|
175
|
+
|
|
149
176
|
# Get source type. Skip any without a useful type
|
|
150
177
|
next if (src_type = type_of(src_path)) == :skip
|
|
151
|
-
|
|
178
|
+
|
|
152
179
|
# Get current lproj (if there is one). Skip if not default or current
|
|
153
180
|
if current_lproj = src_path.match(/^([^\/]+\.lproj)\//).to_a[1]
|
|
154
181
|
next if (current_lproj != default_lproj) && (current_lproj != target_lproj)
|
|
155
182
|
end
|
|
156
|
-
|
|
183
|
+
|
|
157
184
|
# OK, pass all of our validations. Go ahead and build an entry for this
|
|
158
185
|
# Add entry to list of entries for appropriate lproj if localized
|
|
159
186
|
entry = build_entry_for(src_path, src_type)
|
|
@@ -163,8 +190,8 @@ module SproutCore
|
|
|
163
190
|
when target_lproj
|
|
164
191
|
target_lproj_entries[entry.filename] = entry
|
|
165
192
|
else
|
|
166
|
-
|
|
167
|
-
# Be sure to mark any
|
|
193
|
+
|
|
194
|
+
# Be sure to mark any
|
|
168
195
|
entries[entry.filename] = entry
|
|
169
196
|
end
|
|
170
197
|
end
|
|
@@ -178,9 +205,9 @@ module SproutCore
|
|
|
178
205
|
# Finally, entries will need to be grouped by type to allow further processing.
|
|
179
206
|
ret = {}
|
|
180
207
|
entries.values.each { |entry| (ret[entry.type] ||= []) << entry }
|
|
181
|
-
return ret
|
|
208
|
+
return ret
|
|
182
209
|
end
|
|
183
|
-
|
|
210
|
+
|
|
184
211
|
# Determines the type for this manifest entry. Should be one of:
|
|
185
212
|
#
|
|
186
213
|
# stylesheet:: a CSS file
|
|
@@ -188,16 +215,16 @@ module SproutCore
|
|
|
188
215
|
# html:: an HTML file
|
|
189
216
|
#
|
|
190
217
|
# test:: a test file (inside of /tests)
|
|
191
|
-
# fixture:: a fixture file (inside of /fixtures)
|
|
192
|
-
#
|
|
218
|
+
# fixture:: a fixture file (inside of /fixtures)
|
|
219
|
+
#
|
|
193
220
|
# resource:: any other file inside an lproj dir
|
|
194
221
|
# skip:: any other file outside of an lproj dir directories
|
|
195
|
-
#
|
|
222
|
+
#
|
|
196
223
|
# If you need to handle additional types of resources in the future, this is the place to
|
|
197
224
|
# put it.
|
|
198
225
|
#
|
|
199
226
|
# ==== Params
|
|
200
|
-
#
|
|
227
|
+
#
|
|
201
228
|
# src_path:: The source path, relative to source_root.
|
|
202
229
|
#
|
|
203
230
|
def type_of(src_path)
|
|
@@ -221,10 +248,10 @@ module SproutCore
|
|
|
221
248
|
:skip
|
|
222
249
|
end
|
|
223
250
|
end
|
|
224
|
-
|
|
225
|
-
# Build an entry for the resource at the named src_path (relative to the
|
|
226
|
-
# source_root) This should assume we are in going to simply build each
|
|
227
|
-
# resource into the build root without combining files, but not using our
|
|
251
|
+
|
|
252
|
+
# Build an entry for the resource at the named src_path (relative to the
|
|
253
|
+
# source_root) This should assume we are in going to simply build each
|
|
254
|
+
# resource into the build root without combining files, but not using our
|
|
228
255
|
# _src symlink magic.
|
|
229
256
|
def build_entry_for(src_path, src_type, composite=nil, hide_composite = true)
|
|
230
257
|
ret = ManifestEntry.new
|
|
@@ -233,32 +260,32 @@ module SproutCore
|
|
|
233
260
|
ret.original_path = src_path
|
|
234
261
|
ret.hidden = false
|
|
235
262
|
ret.language = language
|
|
236
|
-
|
|
263
|
+
|
|
237
264
|
# the filename is the src_path less any lproj in the front
|
|
238
265
|
ret.filename = src_path.gsub(/^[^\/]+.lproj\//,'')
|
|
239
|
-
|
|
266
|
+
|
|
240
267
|
# the source path is just the combine source root + the path
|
|
241
268
|
ret.source_path = (composite.nil?) ? File.join(bundle.source_root, src_path) : nil
|
|
242
|
-
|
|
243
|
-
# set the composite property. The passed in array should contain other
|
|
244
|
-
# entries if hide_composite is true, then hide the composite items as
|
|
269
|
+
|
|
270
|
+
# set the composite property. The passed in array should contain other
|
|
271
|
+
# entries if hide_composite is true, then hide the composite items as
|
|
245
272
|
# well
|
|
246
273
|
unless composite.nil?
|
|
247
274
|
composite.each { |x| x.hidden = true } if hide_composite
|
|
248
|
-
ret.composite = composite
|
|
275
|
+
ret.composite = composite
|
|
249
276
|
end
|
|
250
|
-
|
|
277
|
+
|
|
251
278
|
# The build path is the build_root + the filename
|
|
252
279
|
# The URL is the url root + the language code + filename
|
|
253
|
-
# also add in _cache or _sym in certain cases. This is just more
|
|
280
|
+
# also add in _cache or _sym in certain cases. This is just more
|
|
254
281
|
# efficient than doing it later.
|
|
255
282
|
url_root = (src_path == 'index.html') ? bundle.index_root : bundle.url_root
|
|
256
283
|
cache_link = nil
|
|
257
284
|
use_source_directly =false
|
|
258
|
-
|
|
259
|
-
# Note: you can only access real resources via the cache. If the entry
|
|
285
|
+
|
|
286
|
+
# Note: you can only access real resources via the cache. If the entry
|
|
260
287
|
# is a composite then do not go through cache.
|
|
261
|
-
if (self.build_mode == :development)
|
|
288
|
+
if (self.build_mode == :development) #&& composite.nil?
|
|
262
289
|
cache_link = '_cache' if CACHED_TYPES.include?(src_type)
|
|
263
290
|
use_source_directly = true if SYMLINKED_TYPES.include?(src_type)
|
|
264
291
|
end
|
|
@@ -271,11 +298,11 @@ module SproutCore
|
|
|
271
298
|
ret.build_path = File.join(*[bundle.build_root, language.to_s, cache_link, ret.filename].compact)
|
|
272
299
|
ret.url = [url_root, language.to_s, cache_link, ret.filename].compact.join('/')
|
|
273
300
|
end
|
|
274
|
-
|
|
301
|
+
|
|
275
302
|
# Done.
|
|
276
303
|
return ret
|
|
277
304
|
end
|
|
278
|
-
|
|
305
|
+
|
|
279
306
|
# Lookup the timestamp on the source path and interpolate that into the filename URL.
|
|
280
307
|
# also insert the _cache element.
|
|
281
308
|
def setup_timestamp_token(entry)
|
|
@@ -285,8 +312,6 @@ module SproutCore
|
|
|
285
312
|
|
|
286
313
|
extname = File.extname(entry.build_path)
|
|
287
314
|
entry.build_path = entry.build_path.gsub(/#{extname}$/,"-#{timestamp}#{extname}") # add timestamp
|
|
288
|
-
|
|
289
|
-
puts "\n\n*setup_timestamp_token(#{entry.url} - #{entry.timestamp})" if /docs-/ =~ entry.url
|
|
290
315
|
end
|
|
291
316
|
end
|
|
292
317
|
|
|
@@ -296,38 +321,55 @@ module SproutCore
|
|
|
296
321
|
# ext:: the file extension
|
|
297
322
|
# source_path:: absolute paths into source that will comprise this resource
|
|
298
323
|
# url:: the url that should be used to reference this resource in the current mode.
|
|
299
|
-
# build_url:: the url that will be used to referene this resource in production.
|
|
324
|
+
# build_url:: the url that will be used to referene this resource in production.
|
|
300
325
|
# build_path:: absolute path to the compiled resource
|
|
301
326
|
# type:: the top-level category
|
|
302
327
|
# original_path:: save the original path used to build this entry
|
|
303
328
|
# hidden:: if true, this entry is needed internally, but otherwise should not be used
|
|
304
|
-
# use_source_directly:: if true, then this entry should be handled via the build symlink
|
|
329
|
+
# use_source_directly:: if true, then this entry should be handled via the build symlink
|
|
305
330
|
# language:: the language in use when this entry was created
|
|
306
|
-
# composite:: If set, this will contain the filenames of other resources that should be combined to form this resource.
|
|
331
|
+
# composite:: If set, this will contain the filenames of other resources that should be combined to form this resource.
|
|
307
332
|
#
|
|
308
|
-
class ManifestEntry < Struct.new(:filename, :ext, :source_path, :url, :build_path, :type, :original_path, :hidden, :use_source_directly, :language
|
|
333
|
+
class ManifestEntry < Struct.new(:filename, :ext, :source_path, :url, :build_path, :type, :original_path, :hidden, :use_source_directly, :language)
|
|
309
334
|
def to_hash
|
|
310
335
|
ret = {}
|
|
311
336
|
self.members.zip(self.values).each { |p| ret[p[0]] = p[1] }
|
|
312
337
|
ret.symbolize_keys
|
|
313
338
|
end
|
|
339
|
+
|
|
340
|
+
def composite; @composite; end
|
|
341
|
+
def composite=(ary); @composite=ary; end
|
|
314
342
|
|
|
315
343
|
def hidden?; !!hidden; end
|
|
316
344
|
def use_source_directly?; !!use_source_directly; end
|
|
317
345
|
def composite?; !!composite; end
|
|
318
|
-
|
|
346
|
+
|
|
319
347
|
def localized?; !!source_path.match(/\.lproj/); end
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
# and tests need to be regenerated whenever you get
|
|
348
|
+
|
|
349
|
+
# Returns true if this entry can be cached even in development mode.
|
|
350
|
+
# Composite resources and tests need to be regenerated whenever you get
|
|
351
|
+
# this.
|
|
323
352
|
def cacheable?
|
|
324
353
|
!composite? && (type != :test)
|
|
325
354
|
end
|
|
355
|
+
|
|
356
|
+
def composite_filenames
|
|
357
|
+
@composite_filenames ||= (composite || []).map { |x| x.filename }
|
|
358
|
+
end
|
|
326
359
|
|
|
327
|
-
# Returns the mtime of the source_path. If this entry is a composite
|
|
328
|
-
# file does not
|
|
360
|
+
# Returns the mtime of the source_path. If this entry is a composite
|
|
361
|
+
# return the latest mtime of the items or if the source file does not
|
|
362
|
+
# exist, returns nil
|
|
329
363
|
def source_path_mtime
|
|
330
|
-
|
|
364
|
+
return @source_path_mtime unless @source_path_mtime.nil?
|
|
365
|
+
|
|
366
|
+
if composite?
|
|
367
|
+
mtimes = (composite || []).map { |x| x.source_path_mtime }
|
|
368
|
+
ret = mtimes.compact.sort.last
|
|
369
|
+
else
|
|
370
|
+
ret = (!File.exists?(source_path)) ? nil : File.mtime(source_path)
|
|
371
|
+
end
|
|
372
|
+
return @source_path_mtime = ret
|
|
331
373
|
end
|
|
332
374
|
|
|
333
375
|
# Returns a timestamp based on the source_path_mtime. If source_path_mtime is nil, always
|
|
@@ -335,12 +377,17 @@ module SproutCore
|
|
|
335
377
|
def timestamp
|
|
336
378
|
(source_path_mtime || Time.now).to_i.to_s
|
|
337
379
|
end
|
|
338
|
-
|
|
380
|
+
|
|
339
381
|
# Returns the content type for this entry. Based on a set of MIME_TYPES borrowed from Rack
|
|
340
382
|
def content_type
|
|
341
383
|
MIME_TYPES[File.extname(build_path)[1..-1]] || 'text/plain'
|
|
342
384
|
end
|
|
343
385
|
|
|
386
|
+
# Returns a URL that takes into account caching requirements.
|
|
387
|
+
def cacheable_url
|
|
388
|
+
[url, timestamp].compact.join('?')
|
|
389
|
+
end
|
|
390
|
+
|
|
344
391
|
# :stopdoc:
|
|
345
392
|
# From WEBrick.
|
|
346
393
|
MIME_TYPES = {
|
|
@@ -400,7 +447,7 @@ module SproutCore
|
|
|
400
447
|
"zip" => "application/zip",
|
|
401
448
|
}
|
|
402
449
|
# :startdoc:
|
|
403
|
-
|
|
450
|
+
|
|
404
451
|
end
|
|
405
|
-
|
|
406
|
-
end
|
|
452
|
+
|
|
453
|
+
end
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
|
|
2
2
|
module SproutCore
|
|
3
|
-
|
|
3
|
+
|
|
4
4
|
# You can use these methods basically copy the contents of your templates
|
|
5
5
|
# directory into a target location.
|
|
6
6
|
module GeneratorHelper
|
|
7
|
-
|
|
7
|
+
|
|
8
8
|
def apply_template(m, root_dir)
|
|
9
9
|
m.directory root_dir
|
|
10
|
-
|
|
10
|
+
|
|
11
11
|
template_directories.each do |d|
|
|
12
12
|
m.directory File.join(root_dir,d)
|
|
13
13
|
end
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
template_files.each do |f|
|
|
16
16
|
f_out = File.join(root_dir,f)
|
|
17
17
|
if f =~ /\.rhtml$/
|
|
@@ -21,9 +21,9 @@ module SproutCore
|
|
|
21
21
|
end
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
|
-
|
|
24
|
+
|
|
25
25
|
def template_directories
|
|
26
|
-
template_files(true)
|
|
26
|
+
template_files(true)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
29
|
def template_files(directories=false, cur_dir=nil,cur_base=nil)
|
|
@@ -48,7 +48,7 @@ module SproutCore
|
|
|
48
48
|
|
|
49
49
|
return ret
|
|
50
50
|
end
|
|
51
|
-
|
|
51
|
+
|
|
52
52
|
def build_client_directories(m, path)
|
|
53
53
|
parts = File.dirname(path).split('/')
|
|
54
54
|
cpath = []
|
|
@@ -57,7 +57,7 @@ module SproutCore
|
|
|
57
57
|
m.directory File.join(cpath)
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
|
-
|
|
60
|
+
|
|
61
61
|
# Convert the Ruby version of the class name to a JavaScript version.
|
|
62
62
|
def client_class_name
|
|
63
63
|
class_name.gsub('::','.')
|
|
@@ -68,56 +68,56 @@ module SproutCore
|
|
|
68
68
|
parts.pop
|
|
69
69
|
return parts * '.'
|
|
70
70
|
end
|
|
71
|
-
|
|
71
|
+
|
|
72
72
|
def controller_class_name
|
|
73
73
|
ret = client_class_name
|
|
74
74
|
ret += 'Controller' unless ret =~ /Controller$/
|
|
75
75
|
ret
|
|
76
76
|
end
|
|
77
|
-
|
|
77
|
+
|
|
78
78
|
def controller_instance_name
|
|
79
79
|
ret = controller_class_name.split('.')
|
|
80
80
|
ret[ret.size-1] = ret.last.underscore.camelize(:lower)
|
|
81
81
|
return ret * "."
|
|
82
82
|
end
|
|
83
|
-
|
|
83
|
+
|
|
84
84
|
def view_class_name
|
|
85
85
|
ret = client_class_name
|
|
86
86
|
ret += 'View' unless ret =~ /View$/
|
|
87
87
|
ret
|
|
88
88
|
end
|
|
89
|
-
|
|
89
|
+
|
|
90
90
|
# This will convert the file_name provided by Rails to one suitable for
|
|
91
91
|
# the client. i.e. calendar/event => calendar/sub_dir/event
|
|
92
92
|
def client_file_path(sub_dir, ext=nil, to_strip = nil, fp = nil)
|
|
93
93
|
parts = (fp.nil? ? file_path : fp).split('/')
|
|
94
|
-
|
|
94
|
+
|
|
95
95
|
# Determine the root dir. Search clients then frameworks.
|
|
96
96
|
loc = @client_location
|
|
97
|
-
|
|
97
|
+
|
|
98
98
|
# check for clients
|
|
99
99
|
if loc.nil?
|
|
100
100
|
client_path = File.join(destination_root, "clients")
|
|
101
101
|
app_name = parts.first
|
|
102
|
-
loc = "clients" if File.exists?(client_path) && Dir.new(client_path).include?(app_name)
|
|
102
|
+
loc = "clients" if File.exists?(client_path) && Dir.new(client_path).include?(app_name)
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
# check for frameworks
|
|
106
106
|
if loc.nil?
|
|
107
107
|
client_path = File.join(destination_root, "frameworks")
|
|
108
108
|
app_name = parts.first
|
|
109
|
-
loc = "frameworks" if File.exists?(client_path) && Dir.new(client_path).include?(app_name)
|
|
109
|
+
loc = "frameworks" if File.exists?(client_path) && Dir.new(client_path).include?(app_name)
|
|
110
110
|
end
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
loc = "clients" if loc.nil? # fallback
|
|
113
|
-
|
|
113
|
+
|
|
114
114
|
path = parts.insert(parts.size-1,sub_dir).unshift(loc) * '/'
|
|
115
|
-
|
|
115
|
+
|
|
116
116
|
# We want to stop the final part of the name for controllers and views.
|
|
117
117
|
if to_strip && (path =~ /_#{to_strip}$/)
|
|
118
118
|
path = path.slice(0,path.size - (to_strip.size + 1))
|
|
119
119
|
end
|
|
120
|
-
|
|
120
|
+
|
|
121
121
|
[path,ext].compact * '.'
|
|
122
122
|
end
|
|
123
123
|
|
|
@@ -125,10 +125,10 @@ module SproutCore
|
|
|
125
125
|
def base_class_name(default_base_class_name = 'SC.Object')
|
|
126
126
|
@args.first || default_base_class_name
|
|
127
127
|
end
|
|
128
|
-
|
|
128
|
+
|
|
129
129
|
###################
|
|
130
130
|
# Borrowed from Rails NamedBase
|
|
131
|
-
|
|
131
|
+
|
|
132
132
|
attr_reader :name, :class_name, :singular_name, :plural_name
|
|
133
133
|
attr_reader :class_path, :file_path, :class_nesting, :class_nesting_depth
|
|
134
134
|
alias_method :file_name, :singular_name
|
|
@@ -163,7 +163,7 @@ module SproutCore
|
|
|
163
163
|
plural = under.pluralize
|
|
164
164
|
[camel, under, plural]
|
|
165
165
|
end
|
|
166
|
-
|
|
166
|
+
|
|
167
167
|
end
|
|
168
168
|
end
|
|
169
169
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
module SproutCore
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
module Helpers
|
|
4
|
-
|
|
4
|
+
|
|
5
5
|
module CaptureHelper
|
|
6
6
|
|
|
7
7
|
# Captures the resulting value of the block and returns it
|
|
@@ -11,32 +11,32 @@ module SproutCore
|
|
|
11
11
|
rescue
|
|
12
12
|
buffer = nil
|
|
13
13
|
end
|
|
14
|
-
|
|
14
|
+
|
|
15
15
|
if buffer.nil?
|
|
16
16
|
block.call(*args).to_s
|
|
17
17
|
else
|
|
18
18
|
pos = buffer.length
|
|
19
19
|
block.call(*args)
|
|
20
|
-
|
|
20
|
+
|
|
21
21
|
# get emitted data
|
|
22
22
|
data = buffer[pos..-1]
|
|
23
|
-
|
|
23
|
+
|
|
24
24
|
# remove from buffer
|
|
25
25
|
buffer[pos..-1] = ''
|
|
26
|
-
|
|
26
|
+
|
|
27
27
|
data
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
|
-
|
|
30
|
+
|
|
31
31
|
# executes the passed block, placing the resulting content into a variable called
|
|
32
32
|
# @content_for_area_name. You can insert this content later by including this
|
|
33
33
|
# variable or by calling yield(:area_name)
|
|
34
34
|
#
|
|
35
|
-
def content_for(name, &block)
|
|
35
|
+
def content_for(name, &block)
|
|
36
36
|
eval "@content_for_#{name} = (@content_for_#{name} || '') + capture(&block)"
|
|
37
37
|
end
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
end
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
end
|
|
42
42
|
end
|