sproutcore 0.9.3 → 0.9.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/History.txt +19 -0
  2. data/Manifest.txt +15 -1
  3. data/clients/view_builder/builders/builder.js +339 -0
  4. data/clients/view_builder/builders/button.js +81 -0
  5. data/clients/view_builder/controllers/document.js +21 -0
  6. data/clients/view_builder/core.js +19 -0
  7. data/clients/view_builder/english.lproj/body.css +77 -0
  8. data/clients/view_builder/english.lproj/body.rhtml +39 -0
  9. data/clients/view_builder/english.lproj/controls.css +0 -0
  10. data/clients/view_builder/english.lproj/strings.js +14 -0
  11. data/clients/view_builder/main.js +38 -0
  12. data/clients/view_builder/mixins/design_mode.js +92 -0
  13. data/clients/view_builder/tests/controllers/document.rhtml +20 -0
  14. data/clients/view_builder/tests/views/builder.rhtml +20 -0
  15. data/clients/view_builder/tests/views/palette.rhtml +21 -0
  16. data/clients/view_builder/views/builder.js +26 -0
  17. data/clients/view_builder/views/palette.js +30 -0
  18. data/frameworks/sproutcore/Core.js +6 -4
  19. data/frameworks/sproutcore/README +1 -3
  20. data/frameworks/sproutcore/controllers/array.js +5 -5
  21. data/frameworks/sproutcore/drag/drag.js +2 -0
  22. data/frameworks/sproutcore/english.lproj/panes.css +16 -35
  23. data/frameworks/sproutcore/foundation/application.js +29 -8
  24. data/frameworks/sproutcore/foundation/object.js +5 -1
  25. data/frameworks/sproutcore/foundation/run_loop.js +65 -2
  26. data/frameworks/sproutcore/foundation/timer.js +1 -0
  27. data/frameworks/sproutcore/globals/window.js +23 -18
  28. data/frameworks/sproutcore/mixins/array.js +2 -2
  29. data/frameworks/sproutcore/mixins/observable.js +127 -52
  30. data/frameworks/sproutcore/panes/dialog.js +1 -1
  31. data/frameworks/sproutcore/panes/overlay.js +6 -2
  32. data/frameworks/sproutcore/panes/pane.js +27 -0
  33. data/frameworks/sproutcore/views/collection/collection.js +1 -1
  34. data/frameworks/sproutcore/views/collection/grid.js +3 -15
  35. data/frameworks/sproutcore/views/collection/source_list.js +10 -5
  36. data/frameworks/sproutcore/views/field/select_field.js +11 -2
  37. data/frameworks/sproutcore/views/field/text_field.js +1 -1
  38. data/frameworks/sproutcore/views/label.js +2 -7
  39. data/frameworks/sproutcore/views/view.js +254 -213
  40. data/generators/client/README +2 -2
  41. data/generators/client/USAGE +2 -2
  42. data/lib/sproutcore/build_tools/html_builder.rb +2 -2
  43. data/lib/sproutcore/bundle_manifest.rb +28 -22
  44. data/lib/sproutcore/merb/bundle_controller.rb +4 -3
  45. data/lib/sproutcore/version.rb +1 -1
  46. metadata +17 -3
  47. data/frameworks/sproutcore/animation/animation.js +0 -411
@@ -1,3 +1,3 @@
1
- Your new SproutCore client application has been created. To access your application, just start sc_sever and visit your client name in the web browser.
1
+ Your new SproutCore client application has been created. To access your application, just start sc-sever and visit your client name in the web browser.
2
2
 
3
- If you want to change the deployment settings for the application, add a section for your client in your environment.yaml.
3
+ If you want to change the deployment settings for your application edit the sc-config.rb file to get started.
@@ -2,11 +2,11 @@ client - Generates a new SproutCore client
2
2
 
3
3
  USAGE:
4
4
 
5
- ./script/generate sc_client client_name
5
+ sc-gen client client_name
6
6
 
7
7
  DISCUSSION:
8
8
 
9
9
  This generator will create a new SproutCore-based JavaScript application. After the generator completes, you will be able to begin work immediately.
10
10
 
11
- The code created by this generator will appear in a /clients directory. To add models, views, and controllers, you can use the additional generators sc_model, sc_controller, sc_object_controller, sc_collection_controller, and sc_view.
11
+ The code created by this generator will appear in a /clients directory. To add models, views, and controllers, you can use the additional generators model, controller, and view.
12
12
 
@@ -45,8 +45,8 @@ module SproutCore
45
45
  end
46
46
 
47
47
  # Clean out any composites we might have collected. They have already
48
- # been expanded.
49
- @entries.reject! { |entry| entry.composite? }
48
+ # been expanded. Also clean out any non-localized rhtml files.
49
+ @entries.reject! { |entry| entry.composite? || (entry.type == :html && !entry.localized?) }
50
50
 
51
51
  # Load any helpers before we continue
52
52
  puts "*************REQUIRE"
@@ -51,17 +51,19 @@ module SproutCore
51
51
  # Builds a manifest for the bundle and the specified language
52
52
  def build!
53
53
 
54
- # STEP 1: Catalog all of the files in the project, including the target language
55
- # and the default language. This will filter out resources not used in this language.
54
+ # STEP 1: Catalog all of the files in the project, including the target
55
+ # language and the default language. This will filter out resources not
56
+ # used in this language.
56
57
  entries = catalog_entries
57
58
 
58
- # STEP 2: Combine the HTML file paths into a single entry, unless this is a framework
59
- if (working = entries[:html]) && working.size > 0
60
- if bundle.can_have_html?
61
- working << build_entry_for('index.html', :html, working)
62
- else
63
- working.each { |x| x.hidden = true }
64
- end
59
+ # STEP 2: Combine the HTML file paths into a single entry, unless this
60
+ # is a framework
61
+ working = entries[:html] ||= []
62
+
63
+ if bundle.can_have_html?
64
+ working << build_entry_for('index.html', :html, working)
65
+ else
66
+ working.each { |x| x.hidden = true }
65
67
  end
66
68
 
67
69
  # STEP 3: If in development build mode:
@@ -148,7 +150,7 @@ module SproutCore
148
150
  if current_lproj = src_path.match(/^([^\/]+\.lproj)\//).to_a[1]
149
151
  next if (current_lproj != default_lproj) && (current_lproj != target_lproj)
150
152
  end
151
-
153
+
152
154
  # OK, pass all of our validations. Go ahead and build an entry for this
153
155
  # Add entry to list of entries for appropriate lproj if localized
154
156
  entry = build_entry_for(src_path, src_type)
@@ -158,6 +160,8 @@ module SproutCore
158
160
  when target_lproj
159
161
  target_lproj_entries[entry.filename] = entry
160
162
  else
163
+
164
+ # Be sure to mark any
161
165
  entries[entry.filename] = entry
162
166
  end
163
167
  end
@@ -198,17 +202,17 @@ module SproutCore
198
202
  case src_path
199
203
  when /^tests\/.+/
200
204
  :test
201
- when /^fixtures\/.+/
205
+ when /^fixtures\/.+\.js$/
202
206
  :fixture
203
- when /.html$/
207
+ when /\.html$/
204
208
  :html
205
- when /.rhtml$/
209
+ when /\.rhtml$/
206
210
  :html
207
- when /.html.erb$/
211
+ when /\.html.erb$/
208
212
  :html
209
- when /.css$/
213
+ when /\.css$/
210
214
  :stylesheet
211
- when /.js$/
215
+ when /\.js$/
212
216
  :javascript
213
217
  when /\.lproj\/.+/
214
218
  :resource
@@ -234,9 +238,10 @@ module SproutCore
234
238
  # the source path is just the combine source root + the path
235
239
  ret.source_path = (composite.nil?) ? File.join(bundle.source_root, src_path) : nil
236
240
 
237
- # set the composite property. The passed in array should contain other entries
238
- # if hide_composite is true, then hide the composite items as well
239
- unless composite.nil? || composite.size == 0
241
+ # set the composite property. The passed in array should contain other
242
+ # entries if hide_composite is true, then hide the composite items as
243
+ # well
244
+ unless composite.nil?
240
245
  composite.each { |x| x.hidden = true } if hide_composite
241
246
  ret.composite = composite.map { |x| x.filename }
242
247
  end
@@ -295,8 +300,7 @@ module SproutCore
295
300
  # hidden:: if true, this entry is needed internally, but otherwise should not be used
296
301
  # use_symlink:: if true, then this entry should be handled via the build symlink
297
302
  # language:: the language in use when this entry was created
298
- # composite:: If set, this will contain the filenames of other resources that should be
299
- # combined to form this resource.
303
+ # composite:: If set, this will contain the filenames of other resources that should be combined to form this resource.
300
304
  #
301
305
  class ManifestEntry < Struct.new(:filename, :ext, :source_path, :url, :build_path, :type, :original_path, :hidden, :use_symlink, :language, :composite)
302
306
  def to_hash
@@ -309,7 +313,9 @@ module SproutCore
309
313
  def use_symlink?; !!use_symlink; end
310
314
  def composite?; !!composite; end
311
315
 
312
- # Returns true if this entry can be cached even in development mode. Composite resources
316
+ def localized?; !!source_path.match(/\.lproj/); end
317
+
318
+ # Returns true if this entry can be cached even in development mode. Composite resources
313
319
  # and tests need to be regenerated whenever you get this.
314
320
  def cacheable?
315
321
  !composite? && (type != :test)
@@ -21,9 +21,10 @@ module SproutCore
21
21
  # the request path to determine which bundle should handle the request.
22
22
  def main
23
23
 
24
- # Before we do anything, set the build_mode for the bundles. This shouldn't change
25
- # during execution, but if we set this during the router call, the Merb.environment
26
- # is sometimes not ready yet.
24
+ # Before we do anything, set the build_mode for the bundles. This
25
+ # shouldn't change during execution, but if we set this during the
26
+ # router call, the Merb.environment is sometimes not ready yet.
27
+ #
27
28
  if ::Merb.environment.to_sym == :production
28
29
  Bundle.build_mode = :production
29
30
  else
@@ -2,7 +2,7 @@ module SproutCore #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 9
5
- TINY = 3
5
+ TINY = 4
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sproutcore
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3
4
+ version: 0.9.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Charles Jolley
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-04-25 00:00:00 -07:00
12
+ date: 2008-05-05 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -106,10 +106,24 @@ files:
106
106
  - clients/sc_test_runner/models/test.js
107
107
  - clients/sc_test_runner/views/runner_frame.js
108
108
  - clients/sc_test_runner/views/test_label.js
109
+ - clients/view_builder/builders/builder.js
110
+ - clients/view_builder/builders/button.js
111
+ - clients/view_builder/controllers/document.js
112
+ - clients/view_builder/core.js
113
+ - clients/view_builder/english.lproj/body.css
114
+ - clients/view_builder/english.lproj/body.rhtml
115
+ - clients/view_builder/english.lproj/controls.css
116
+ - clients/view_builder/english.lproj/strings.js
117
+ - clients/view_builder/main.js
118
+ - clients/view_builder/mixins/design_mode.js
119
+ - clients/view_builder/tests/controllers/document.rhtml
120
+ - clients/view_builder/tests/views/builder.rhtml
121
+ - clients/view_builder/tests/views/palette.rhtml
122
+ - clients/view_builder/views/builder.js
123
+ - clients/view_builder/views/palette.js
109
124
  - config/hoe.rb
110
125
  - config/requirements.rb
111
126
  - frameworks/prototype/prototype.js
112
- - frameworks/sproutcore/animation/animation.js
113
127
  - frameworks/sproutcore/controllers/array.js
114
128
  - frameworks/sproutcore/controllers/collection.js
115
129
  - frameworks/sproutcore/controllers/controller.js
@@ -1,411 +0,0 @@
1
- // ========================================================================
2
- // SproutCore
3
- // copyright 2006-2008 Sprout Systems, Inc.
4
- // ========================================================================
5
-
6
- require('Core') ;
7
- require('foundation/timer') ;
8
-
9
- /**
10
- @class
11
-
12
- An animator is a special timer that will transition its value property from
13
- 0 to 1 according to a transform function you define. You can also specify
14
- one or more "subjects" that will be invoked whenever the animation value
15
- changes, which can apply the animation to any target you like.
16
-
17
- This class and its related classes are based on Bernie's Better Animator
18
- class.
19
-
20
- Use Cases:
21
-
22
- 1. I just want to transition from x=0 -> x=20.
23
- v.transitionTo('styleLeft', 20) ;
24
- -> creates an animation for styleLeft. If you add a new animation for
25
- the same effect, it will cancel the old one automatically.
26
-
27
- 2. I want to have an 'animation behavior' attached to some property.
28
- whenever I change it, it should automatically transition the property
29
- instead of just updating it. i.e. a "Tracker".
30
-
31
- -> I may want the tracker to update several things at once. But that
32
- could be done through changing one property which will in turn
33
- update everything else. Better idea.
34
-
35
- Tracker simply stores some animation properties and calls transitionTo
36
- whenever your target value changes.
37
-
38
- 3. I want to have some property animating on its own. For example a
39
- throbbing button
40
-
41
- a = v.addAnimation('opacity', {
42
- repeatCount: ,
43
- autoreverses: YES,
44
- end: 1.0,
45
- start: 0.0,
46
- property: 'opacity'
47
- }) ;
48
-
49
- a.set('isPaused', YES) ;
50
- v.removeAnimation('opacity');
51
-
52
- --
53
- We will need an animation builder. It would be nice if I could have a
54
- complete timeline for an animation setup and you just tell it to run. Set
55
- the timecode to anytime that you want, tell it to start or stop.
56
-
57
- @extends SC.Timer
58
- @author Charles Jolley
59
- @since SproutCore 1.0
60
- */
61
- SC.Animation = SC.Timer.extend(
62
- /** @scope SC.Animation.prototype */ {
63
-
64
- /**
65
- The target frame rate. This is used to determine the interval of the
66
- timer.
67
-
68
- @type {Number}
69
- @field
70
- */
71
- frameRate: 60,
72
-
73
- /**
74
- The interval between frames. Calculated automatically from the frameRate.
75
- This property is read only.
76
-
77
- @type {Number}
78
- @field
79
- */
80
- interval: function() {
81
- return 1000 / this.get('frameRate') ;
82
- }.property('frameRate'),
83
-
84
- /**
85
- The total amount of time in msec you want to take for the animation to
86
- go from 0-1.
87
- */
88
- duration: 0,
89
-
90
- /**
91
- The speed at which the timecode for the animation will progress. 1.0
92
- means it will progress in real time, 2.0 means twice as fast, etc.
93
- */
94
- speed: 1.0,
95
-
96
- /**
97
- The total number of times you want the animation to repeat.
98
-
99
- This can be any number, including partial numbers. If you set this
100
- value you must not set repeatDuration as well. This will be ignored
101
- if the value is 0, which is the default.
102
-
103
- If you set this property to -1, then the animation will repeat
104
- indefinitely.
105
-
106
- Setting this property will update the targetTimecode.
107
-
108
- @type {Number}
109
- @field
110
- */
111
- repeatCount: 0,
112
-
113
- /**
114
- The total amount of time the animation should run, repeating itself, in
115
- msec.
116
-
117
- If you set this value you must not set repeatCount as well. This will
118
- be ignored if the value is 0, which is the default.
119
-
120
- Setting this property will update the targetTimecode.
121
-
122
- @type {Number}
123
- @field
124
- */
125
- repeatDuration: 0,
126
-
127
- /**
128
- If YES, then the animation will automatically reverse itself on each
129
- repeat.
130
-
131
- @type {Boolean}
132
- @field
133
- */
134
- autoreverses: NO,
135
-
136
- /**
137
- A transition function. This is used to convert the progress into a
138
- state value. You can supply your own transition function to provide
139
- varied behaviors such as ease in, ease out, etc.
140
-
141
- The function must have a signature like:
142
-
143
- transition: function(value, animator)
144
-
145
- It must accept a value from 0-1 indicating the current animation progress
146
- and return a value from 0-1 indication the current transition progress.
147
-
148
- @type {Function}
149
- @field
150
- */
151
- transition: null,
152
-
153
- /**
154
- This is the current timecode for the animation, in msec. You can set
155
- this to any value that you want and the animation to compute the current
156
- transition value from it.
157
-
158
- To move instantly to any part of your animation, you can simply set this
159
- timecode or use jumpTo().
160
-
161
- @type {Number}
162
- @field
163
- */
164
- currentTimecode: 0,
165
-
166
- /**
167
- This is the target timecode. Whenever the target timecode and the
168
- current timecode do not match, the animation will animate until it
169
- reaches the target timecode.
170
-
171
- To transition the animation to a new state, set the timecode to any
172
- value that you want.
173
-
174
- @type {Number}
175
- */
176
- targetTimecode: 0,
177
-
178
- /**
179
- The current animation progress.
180
-
181
- This value will loop from 0-1 based on the current timecode and the
182
- setting of autoreverses. You generally do not want to use this value.
183
- Instead use the value property to compute the current transition.
184
-
185
- @type {Number}
186
- @field
187
- */
188
- progress: function() {
189
-
190
- // current progress is calculated from the currentTimecode by dividing
191
- // it by the animation duration and autoreverses.
192
- var currentTimecode = this.get('currentTimecode') ;
193
- var duration = this.get('duration') ;
194
- var reverses = this.get('autoreverses') ;
195
-
196
- // find the progress through the current cycle.
197
- var cycle = Math.floor(currentTimecode / duration) ;
198
- var progress = (currentTimecode - (duration * cycle)) / duration;
199
-
200
- // if we autoreverse and the cycle is odd numbered, invert.
201
- if (reverses && (cycle % 2) > 0) progress = 1 - progress ;
202
- return progress ;
203
- }.property('currentTimecode', 'duration', 'autoreverses'),
204
-
205
- /**
206
- The current animation value. Transform functions can observe this
207
- property and update the target object accordingly.
208
-
209
- @type {Number}
210
- @field
211
- */
212
- value: function() {
213
- var value = this.get('progress');
214
- if (this.transition) value = this.transition(value, this) ;
215
- return value ;
216
- }.property('progress'),
217
-
218
- /**
219
- The target object of the animation. This is often used by transform
220
- functions as the target of their change. It is not strictly required.
221
-
222
- @type {Object}
223
- @field
224
- */
225
- target: null,
226
-
227
-
228
- /**
229
- This method must be called once when the animation is created to schedule
230
- it with the run loop. Once animation has been started, you should can
231
- pause it to remove it from the runloop temporarily.
232
-
233
- @returns {void}
234
- */
235
- play: function() {
236
- this.beginPropertyChanges() ;
237
- if (!this.get('isScheduled')) {
238
- this.schedule() ;
239
- this._lastActionTime = SC.runLoop.get('startTime') ;
240
- }
241
-
242
- if (this.get('isPaused')) this.set('isPaused', NO) ;
243
- this.endPropertyChanges() ;
244
- },
245
-
246
- /**
247
- Once an animation has been started, you can pause it anytime with this
248
- method. Call start() to restart it or set isPaused to NO.
249
-
250
- @returns {void}
251
- */
252
- pause: function() {
253
- this.set('isPaused', YES) ;
254
- },
255
-
256
- /**
257
- Immediately changes the currentTimecode to reflect the requested amount
258
- of progress through a single cycle of the animation.
259
-
260
- @param progress {Number} a progress value from 0 to 1.
261
- @returns {void}
262
- */
263
- jumpTo: function(progress) {
264
- // get the current progress.
265
- var cur = this.get('progress') ;
266
- var diff = progress - cur ;
267
- var duration = this.get('duration') ;
268
- diff *= duration ;
269
-
270
- var timecode = this.get('currentTimecode') ;
271
- if (diff !== 0) this.set('currentTimecode', timecode + diff) ;
272
- },
273
-
274
- /**
275
- Changes the targetTimecode to reflect the request amount of progress
276
- through the current cycle of the animation. If the animation is in
277
- reverse, this could move the timecode in the opposite direction.
278
-
279
- @param progress {Number} a progress value from 0 to 1.
280
- @returns {void}
281
- */
282
- seekTo: function(progress) {
283
- // get the current progress.
284
- var cur = this.get('progress') ;
285
- var diff = progress - cur ;
286
- var duration = this.get('duration') ;
287
- diff *= duration ;
288
-
289
- var timecode = this.get('currentTimecode') ;
290
- if (diff !== 0) this.set('targetTimecode', timecode + diff) ;
291
- },
292
-
293
- /**
294
- Changes the currentTimecode and targetTimecode to reflect the requested
295
- amount of progress through the current cycle of the animation. If the
296
- animation is in reverse, this could move the timecode in the opposite
297
- direction.
298
-
299
- @param fromProgress {Number} a progress value from 0 to 1
300
- @param toProgress {Number} a progress value from 0 to 1
301
- @returns {void}
302
- */
303
- seekFromTo: function(fromProgress, toProgress) {
304
- // get the current progress.
305
- var timecode = this.get('currentTimecode') ;
306
- var cur = this.get('progress') ;
307
- var duration = this.get('duration') ;
308
-
309
- this.beginPropertyChanges() ;
310
-
311
- var diff = fromProgress - cur ;
312
- diff *= duration ;
313
- if (diff !== 0) this.set('currentTimecode', timecode + diff) ;
314
-
315
- diff = toProgress - cur ;
316
- diff *= duration ;
317
- if (diff !== 0) this.set('targetTimecode', timecode + diff) ;
318
-
319
- this.endPropertyChanges() ;
320
- },
321
-
322
- /**
323
- Changes the targetTimecode to invert the direction of the animation.
324
- If the progress value is currently headed towards 1.0, it will be instead
325
- headed to 0.
326
-
327
- @returns {Number} the new progress
328
- */
329
- toggle: function() {
330
- throw "toggle not yet implemented" ;
331
- },
332
-
333
- /**
334
- The core action executed by the timer.
335
- */
336
- performAction: function() {
337
-
338
- // if timecodes match, then we suspend the animation and return, there
339
- // is nothing more to do.
340
- var cur = this.get('currentTimecode') ;
341
- var target = this.get('targetTimecode') ;
342
- if (cur == target) {
343
- this.set('isPaused', YES) ;
344
- return ;
345
- }
346
-
347
- // determine the amount of time that has elapsed since the last time
348
- // we were called.
349
- var curTime = SC.runLoop.get('startTime') ;
350
- var lapsed = (curTime - this._lastActionTime) * this.get('speed') ;
351
- this._lastActionTime = curTime ;
352
-
353
- // update the current timecode. Moving in the direction of the target
354
- // timecode. If timecodes match, there is nothing to do.
355
- if (target > cur) {
356
- cur += lapsed ;
357
- if (cur > target) cur = target ;
358
- } else {
359
- cur -= lapsed ;
360
- if (cur < target) cur = target ;
361
- }
362
-
363
- // now set the new timecode, this should trigger other observers to
364
- // update.
365
- this.set('currentTimecode', cur) ;
366
- },
367
-
368
- // ......................................
369
- // INTERNAL METHODS
370
- //
371
-
372
- /** @private
373
- Observes changes to repeatCount; updates the targetTimecode.
374
- */
375
- _repeatCountObserver: function() {
376
- var repeatCount = this.get('repeatCount') ;
377
- var target ;
378
- if (repeatCount < 0) {
379
- target = Date.now() * 2 ;
380
- } else if (repeatCount > 0) {
381
- target = this.get('duration') * repeatCount ;
382
- } else return ; // nothing to do.
383
- this.set('targetTimecode', target) ;
384
- }.observes('repeatCount'),
385
-
386
- /** @private
387
- Observes changes to the repeatDuration; updates the targetTimecode.
388
- */
389
- _repeatDurationObserver: function() {
390
- var dur = this.get('repeatDuration') ;
391
- if (dur < 0) {
392
- dur = Date.now() * 2 ;
393
- } else if (dur == 0) return; // nothing to do
394
- this.set('targetTimecode', dur) ;
395
- }.observes('repeatDuration'),
396
-
397
- init: function() {
398
- arguments.callee.base.call(this) ;
399
-
400
- this.targetTimecode = this.get('duration') ;
401
- this._repeatDurationObserver() ;
402
- this._repeatCountObserver() ;
403
- },
404
-
405
- repeats: YES, // for timer
406
-
407
- _logValueObserver: function() {
408
- console.log('value did change to: %@'.fmt(this.get('value')));
409
- }.observes('value')
410
-
411
- });