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
@@ -1,6 +1,6 @@
1
1
  # SPROUTCORE CONFIGURATION FILE
2
- # Use this file to customize the URLs, source and output paths and and other
3
- # options used by the SproutCore build system to create the output for your
2
+ # Use this file to customize the URLs, source and output paths and other
3
+ # options used by the SproutCore build system to create the output for your
4
4
  # SproutCore applications.
5
5
 
6
6
  # If you want to use the libraries provided by other gems, require those gems
@@ -9,10 +9,10 @@
9
9
  #
10
10
  # require 'sproutcore'
11
11
 
12
- # This configuration section will be applied to all bundles used by your
12
+ # This configuration section will be applied to all bundles used by your
13
13
  # application, even bundles that come from other gems.
14
14
  config :all do |c|
15
-
15
+
16
16
  # Name any other frameworks your bundles depend upon. The stylesheets and
17
17
  # JavaScript for required bundles will be loaded before your bundle on your
18
18
  # page.
@@ -21,44 +21,60 @@ config :all do |c|
21
21
  # This string will be prepended before any URLs that reference JavaScript,
22
22
  # CSS or images in your files.
23
23
  c[:resources_at] = 'static'
24
-
24
+
25
25
  # This string will be prepended before any index.html urls that actually
26
26
  # load your clients. Setting this to an empty string will mount all
27
27
  # of your clients at the root URL level.
28
28
  c[:index_at] = ''
29
-
30
- # If you also need to load external stylesheets not managed by the bundle
29
+
30
+ # If you also need to load external stylesheets not managed by the bundle
31
31
  # system, name the URLs you want to reference here.
32
32
  # c[:stylesheet_libs] = ['/stylesheets/public.css']
33
-
33
+
34
34
  # If you also need to load external javascripts not managed by the bundle
35
- # system, name hte URLs you want to reference here. These will be loaded
35
+ # system, name the URLs you want to reference here. These will be loaded
36
36
  # automatically.
37
37
  # c[:javascript_libs] = ['/javascript/scriptaculous.js']
38
38
 
39
39
  # This is the preferred language. When the user visits the root URL of
40
- # your client, this is the language they will get. When looking for a
40
+ # your client, this is the language they will get. When looking for a
41
41
  # resources (such as an image or stylesheet), SproutCore will also try
42
42
  # your preferred language .lproj if it cannot find the resource in the
43
43
  # current language.
44
44
  # c[:preferred_language] = :fr
45
-
45
+
46
46
  # If you want to use a default root layout template other than the default
47
- # provided by SproutCore, you can specifiy the path name to the index.html
47
+ # provided by SproutCore, you can specifiy the path name to the index.html
48
48
  # here. If you provide a relative path, SproutCore will assume the file
49
49
  # is relative to the root of this project.
50
50
  # c[:layout] = 'lib/index.rhtml'
51
-
51
+
52
52
  # This is the fully qualified path to the directory you want all of your
53
53
  # static files stored in. You can place any files not managed by the build
54
- # system here. SproutCore will also save its cached resources here.
54
+ # system here. SproutCore will also save its cached resources here.
55
55
  # c[:public_root] = File.join(File.dirname(__FILE__), 'public')
56
-
56
+
57
57
  # The default build mode. Normally you can specify this on the command
58
- # line as well using the -e option, but you can override the default
58
+ # line as well using the -e option, but you can override the default
59
59
  # using this config as well.
60
60
  #c[:build_mode] = :production
61
+
62
+ # Name the build modes that you want JavaScript to be minified in. Normally
63
+ # JavaScript is only minified in production. This only has effect if you
64
+ # are also building composite javascript in the same mode.
65
+ #c[:minify_javascript] = :production
61
66
 
67
+ # Name the build modes that you want your JavaScript to appear as a
68
+ # composite file instead of the individual parts. This can be an array.
69
+ #c[:combine_javascript] = :production
70
+
71
+ # Name the builds modes that you want you CSS to appear as compite files
72
+ # instead of individual parts. This can be an array.
73
+ #c[:combine_stylesheets] = :production
74
+
75
+ # Name the build modes that should include fixture data.
76
+ #c[:include_fixtures] = :development
77
+
62
78
  end
63
79
 
64
80
  # Add configurations for specific bundles here as well. Any options you
@@ -69,4 +85,3 @@ end
69
85
  # c[:required] = [:sproutcore, :shared]
70
86
  # end
71
87
  #
72
-
data/bin/sc-build CHANGED
@@ -59,27 +59,27 @@ opts = OptionParser.new do |opts|
59
59
  opts.on("-e", "--enviroment=MODE", "Set the build mode for the system. Normally you want to build in production mode (which is the default if you do not include this option), but you can use this switch to build in development mode for testing.") do |opt_build_mode|
60
60
  build_mode = opt_build_mode.to_s.downcase.to_sym
61
61
  end
62
-
62
+
63
63
  opts.on("-t", "--target=PATH", "Set the target path for your build. Normally this will be set to tmp/build in the working directory") do |opt_target|
64
64
  build_root = File.expand_path(opt_target)
65
65
  end
66
-
66
+
67
67
  opts.on("-l", "--library=PATH", "The library root you want to use. Normally sc-build will use the working directory. If you want to point to another project on disk to build from, use this option.") do |opt_library|
68
68
  library_root = File.expand_path(opt_library)
69
69
  end
70
-
70
+
71
71
  opts.on("-r", "--[no-]include-required", "If passed when building a single client, then the build tool will also find any required bundles and build them as well.") do |opt_req|
72
72
  include_dependencies = !!opt_req
73
73
  end
74
-
74
+
75
75
  opts.on("-v", "--[no-]verbose", "If set, extra debug output will be displayed during the build") do |opt_verbose|
76
76
  verbose = !!opt_verbose
77
77
  end
78
-
78
+
79
79
  opts.on("-L", "--languages=LANGUAGE", "Pass a comma separated list of the specific languages you want to build. If you do not pass this option, the build tool will build all languages required by the bundles to function") do |opt_lang|
80
80
  languages = opt_lang.split(',').map { |x| x.to_sym }
81
81
  end
82
-
82
+
83
83
  opts.on("-c", "--[no-]clean", "If set, then the build tool will delete a bundle's output before it builds it, so you get a clean build") do |opt_clean|
84
84
  clean = !!opt_clean
85
85
  end
@@ -87,14 +87,14 @@ opts = OptionParser.new do |opts|
87
87
  opts.on('-d', '--[no-]docs', "Include documentation") do |opt_docs|
88
88
  docs = !!opt_docs
89
89
  end
90
-
90
+
91
91
  end
92
92
  opts.parse!
93
93
 
94
94
  ############################################################
95
95
  ## SETUP ENVIRONMENT
96
96
  ##
97
-
97
+
98
98
  # Configure logger
99
99
  SC.logger.level = (verbose) ? Logger::DEBUG : Logger::INFO
100
100
  SC.logger.progname = $0
@@ -120,15 +120,15 @@ if bundle_name
120
120
  else
121
121
  bundles = [bundle]
122
122
  end
123
-
123
+
124
124
  SC.logger.info("Building: #{bundles.map { |x| x.bundle_name } * ', ' }...")
125
-
125
+
126
126
  # No bundle provided, get all bundles for library
127
127
  else
128
128
  bundles = library.bundles
129
129
  SC.logger.info("Building ALL bundles:\n #{bundles.map { |x| x.bundle_name } * ', '}...")
130
- end
131
-
130
+ end
131
+
132
132
  ############################################################
133
133
  ## BUILD EACH BUNDLE
134
134
  ##
@@ -140,19 +140,19 @@ SC.logger.info("Selected Languages: #{languages.join(', ')}")
140
140
  SC.logger.info('')
141
141
  bundles.each do |bundle|
142
142
  SC.logger.info("Building #{bundle.bundle_name} > #{bundle.build_root}...")
143
-
143
+
144
144
  if clean
145
145
  SC.logger.debug("~ Cleaning #{bundle.build_root}")
146
146
  FileUtils.rm_rf(bundle.build_root)
147
147
  end
148
-
148
+
149
149
  bundle.build(*languages)
150
-
150
+
151
151
  if docs
152
152
  SC.logger.debug('~ Building docs')
153
- SC::JSDoc.generate(:bundle => bundle)
153
+ SC::JSDoc.generate(:bundle => bundle)
154
154
  end
155
-
155
+
156
156
  end
157
157
 
158
158
  SC.logger.debug("")
data/bin/sc-server CHANGED
@@ -63,7 +63,7 @@ end
63
63
  ############################################################
64
64
  ## Start Merb
65
65
  ##
66
-
66
+
67
67
  puts "Running SproutCore Build Tools v#{SproutCore::VERSION::STRING}"
68
68
  puts "Welcome to SproutCore"
69
69
  Merb.start
data/bin/sproutcore CHANGED
@@ -26,12 +26,12 @@ if ARGV.first == 'freeze:edge'
26
26
  puts `svn co http://sproutcore.googlecode.com/svn/trunk/frameworks/#{framework} #{File.join('frameworks', framework)}`
27
27
  end
28
28
  end
29
-
29
+
30
30
  exit(0)
31
31
  end
32
-
32
+
33
33
  require 'rubigen/scripts/generate'
34
- source = RubiGen::PathSource.new(:application,
34
+ source = RubiGen::PathSource.new(:application,
35
35
  File.join(File.dirname(__FILE__), "../app_generators"))
36
36
  RubiGen::Base.reset_sources
37
37
  RubiGen::Base.append_sources source
@@ -2,5 +2,4 @@
2
2
  <h1>Client Has No Tests</h1>
3
3
  <p style="font-size: 15px;">This client does not currently have any unit tests. To add a unit test, open a terminal to the root directly and type:</p>
4
4
  <p style="font-size: 15px; text-align:center;"><code>./script/generate sc_test <%= label_view :outlet => true, :tag => 'span', :bind => { :content => 'TestRunner.runnerController.clientName' } %>/<b>test_name</b></code></p>
5
- </div>
6
5
  <% end %>
data/config/hoe.rb CHANGED
@@ -30,21 +30,21 @@ Run 'rubyforge setup' to prepare your env for access to Rubyforge
30
30
  end
31
31
 
32
32
 
33
- REV = nil
34
- # UNCOMMENT IF REQUIRED:
33
+ REV = nil
34
+ # UNCOMMENT IF REQUIRED:
35
35
  #REV = `svn info`.each {|line| if line =~ /^Revision:/ then k,v = line.split(': '); break v.chomp; else next; end} rescue nil
36
36
  VERS = SproutCore::VERSION::STRING + (REV ? ".#{REV}" : "")
37
37
  RDOC_OPTS = ['--quiet', '--title', 'sproutcore documentation',
38
38
  "--opname", "index.html",
39
- "--line-numbers",
39
+ "--line-numbers",
40
40
  "--main", "README",
41
41
  "--inline-source"]
42
42
 
43
43
  class Hoe
44
- def extra_deps
45
- @extra_deps.reject! { |x| Array(x).first == 'hoe' }
44
+ def extra_deps
45
+ @extra_deps.reject! { |x| Array(x).first == 'hoe' }
46
46
  @extra_deps
47
- end
47
+ end
48
48
  end
49
49
 
50
50
  # Generate all the Rake tasks
@@ -57,13 +57,13 @@ hoe = Hoe.new(GEM_NAME, VERS) do |p|
57
57
  p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
58
58
  p.test_globs = ["spec/**/*_spec.rb"]
59
59
  p.clean_globs |= ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store'] #An array of file patterns to delete on clean.
60
-
60
+
61
61
  # == Optional
62
62
  p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
63
63
  p.extra_deps = [['activesupport', '>= 2.0.2'], ['merb-core', '>= 0.9.1'], ['erubis'], ['rubigen'], ['mongrel']]
64
-
64
+
65
65
  #p.spec_extras = {} # A hash of extra values to set in the gemspec.
66
-
66
+
67
67
  end
68
68
 
69
69
  CHANGES = hoe.paragraphs_of('History.txt', 0..1).join("\\n\\n")
@@ -14,4 +14,4 @@ end
14
14
 
15
15
  $:.unshift(File.join(File.dirname(__FILE__), %w[.. lib]))
16
16
 
17
- require 'sproutcore'
17
+ require 'sproutcore'
@@ -1,4 +1,18 @@
1
1
 
2
+ == sproutcore 0.9.12
3
+
4
+ - SC.ButtonView & SC.MenuItemView now removes and adds the 'active' class name on mouseExited and mouseEntered when the mouse is pressed to provide better indication of whether an action will occur on mouse up. (Thanks schwa23)
5
+
6
+ - SC.Record#toString now shows record type in description.
7
+
8
+ - [FIX] SC.Timer now computes the next fire time before it executes your callback action. This should avoid the situation where a timer would call your action, which would then take it past the last time it should fire and hence the last fire would never happen. (Thanks August)
9
+
10
+ - [FIX] SC.Record#matchCondition() did not behave correctly when comparing record instances. Fix by onitunes includes both a faster comparison method along with correct behavior + kickin' unit tests
11
+
12
+ - [FIX] some settings on the inline editor for multi-line edits were wrong. Now fixed thanks to maloninc (#38)
13
+
14
+ == sproutcore 0.9.11
15
+
2
16
  - [FIX] innerFrame tests were failing. Now working.
3
17
 
4
18
  - Progress bar now shows 100% fill when set to indeterminate. This should
@@ -41,7 +41,7 @@
41
41
 
42
42
  // All objects live in the SproutCore namespace, which is also availabe in the
43
43
  // abreviation SC.
44
- if (!SC) SC = {}; SproutCore = SC ;
44
+ if (!window.SC) SC = {}; SproutCore = SC ;
45
45
 
46
46
  // this makes for some nicer to read code
47
47
  var YES = true ; var NO = false ;
@@ -170,6 +170,7 @@ body.sc-theme {
170
170
  text-transform: uppercase;
171
171
  font-size: 11px;
172
172
  font-weight: bold ;
173
+ text-overflow:hidden;
173
174
  }
174
175
 
175
176
  .sc-theme .sc-collection-view .sc-source-list-group .sc-source-list-label.sel {
@@ -306,7 +306,7 @@ SC.Binding.MultipleNoError = SC.Binding.NoError.ext(SC.Binding.Multiple);
306
306
  // Converts value to a bool. true if: not null, not empty array, not 0, '',
307
307
  // etc.
308
308
  SC.Binding.Bool = SC.Binding.build(function(d,k,v) {
309
- return ($type(v) == T_ARRAY) ? (t.length > 0) : !!v ;
309
+ return ($type(v) == T_ARRAY) ? (v.length > 0) : !!v ;
310
310
  }) ;
311
311
 
312
312
  // Converts value to a bool, but its only true if not null
@@ -316,7 +316,7 @@ SC.Binding.NotNull = SC.Binding.build(function(d,k,v) {
316
316
 
317
317
  // Converts inverse of bool.
318
318
  SC.Binding.Not = SC.Binding.build(function(d,k,v) {
319
- return !(($type(v) == T_ARRAY) ? (t.length > 0) : !!v) ;
319
+ return !(($type(v) == T_ARRAY) ? (v.length > 0) : !!v) ;
320
320
  }) ;
321
321
 
322
322
  // Converts value to a bool, but its only true if not null
@@ -241,20 +241,7 @@ SC.Timer = SC.Object.extend(
241
241
  @field
242
242
  @type {Number}
243
243
  */
244
- fireTime: function() {
245
- if (this._invalid || !this.get('isValid')) return 0;
246
-
247
- var now = Date.now() ;
248
- var start = this.get('startTime') || now ;
249
- if (this.until && this.until > 0 && now >= this.until) return 0;
250
-
251
- var interval = this.get('interval') ;
252
- var cycle = Math.ceil(((now - start) / interval)+0.01) ;
253
- if ((cycle > 1) && !this.repeats) return 0 ;
254
-
255
- if (cycle < 1) cycle = 1 ;
256
- return start + (cycle * interval) ;
257
- }.property(),
244
+ fireTime: null,
258
245
 
259
246
  /**
260
247
  Invalidates the timer so that it will not execute again. If a timer has
@@ -280,11 +267,15 @@ SC.Timer = SC.Object.extend(
280
267
  @returns {void}
281
268
  */
282
269
  fire: function() {
283
- if (this.get('isPaused') === NO) {
284
- this.performAction() ;
285
- }
286
270
 
287
- (this.repeats && (this.get('fireTime')>0)) ? this.schedule() : this.invalidate() ;
271
+ // whenever the timer fires, calculate the next fireTime immediately.
272
+ var nextFireTime = this._computeNextFireTime();
273
+
274
+ // now perform the fire action unless paused.
275
+ if (!this.get('isPaused')) this.performAction() ;
276
+
277
+ // reschedule the timer if needed...
278
+ (nextFireTime>0) ? this.schedule() : this.invalidate();
288
279
  },
289
280
 
290
281
  /**
@@ -325,10 +316,25 @@ SC.Timer = SC.Object.extend(
325
316
  @returns {SC.Timer} The receiver
326
317
  */
327
318
  schedule: function() {
319
+
320
+ this.beginPropertyChanges();
321
+
322
+ // if start time was not set explicitly when the timer was created,
323
+ // get it from the run loop. This way timer scheduling will always
324
+ // occur in sync.
325
+ if (!this.startTime) this.set('startTime', SC.runLoop.get('startTime')) ;
326
+
327
+ // If this is the first time the timer was scheduled, compute the fireTime
328
+ var fireTime = (this.fireTime) ? this.get('fireTime') : this._computeNextFireTime() ; // sets the fire time...
329
+
330
+ // now schedule the timer if needed.
328
331
  if (!this._invalid) {
329
332
  this.set('isScheduled', YES) ;
330
- SC.runLoop.scheduleTimer(this, this.get('fireTime')) ;
333
+ SC.runLoop.scheduleTimer(this, fireTime) ;
331
334
  }
335
+
336
+ this.endPropertyChanges() ;
337
+
332
338
  return this ;
333
339
  },
334
340
 
@@ -343,15 +349,42 @@ SC.Timer = SC.Object.extend(
343
349
  if (this.until instanceof Date) {
344
350
  this.until = this.until.getTime() ;
345
351
  }
346
-
347
- // if start time was not set, get it from the run loop.
348
- if (!this.startTime) this.startTime = SC.runLoop.get('startTime') ;
349
352
  },
350
353
 
351
354
  // if the paused state changes, notify the runloop so that it can
352
355
  // reschedule its timeout.
353
356
  _isPausedObserver: function() {
354
357
  SC.runLoop.timerPausedStateDidChange(this) ;
358
+ }.observes('isPaused'),
359
+
360
+ /** @private
361
+ Computes the next fireTime and updates the property.
362
+
363
+ @returns the next fire time (also set on fireTime property)
364
+ */
365
+ _computeNextFireTime: function() {
366
+
367
+ var fireTime = 0 ;
368
+ if (!this._invalid && this.get('isValid')) {
369
+
370
+ var now = Date.now() ;
371
+ var start = this.get('startTime') || now ;
372
+ var until = this.get('until') ;
373
+
374
+ // only calculate if we have not passed unitl.
375
+ if ((!until) || (until === 0) || (now < until)) {
376
+
377
+ var interval = this.get('interval') ;
378
+ var repeats = this.get('repeats') ;
379
+ var cycle = Math.ceil(((now - start) / interval)+0.01) ;
380
+ if (cycle < 1) cycle = 1 ;
381
+
382
+ fireTime = ((cycle <= 1) || repeats) ? start + (cycle * interval) : 0;
383
+ }
384
+ }
385
+
386
+ this.setIfChanged('fireTime', fireTime) ;
387
+ return fireTime ;
355
388
  }
356
389
 
357
390
  }) ;
@@ -8,8 +8,7 @@
8
8
  # See the comments in this file for more information on what you can
9
9
  # change.
10
10
  -%>
11
- <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
12
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
11
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
13
12
  <html>
14
13
  <head>
15
14
  <meta http-equiv="Content-type" content="text/html; charset=utf-8" />
@@ -28,7 +27,7 @@
28
27
  </head>
29
28
  <body class="<%= @theme || 'sc-theme' %> focus">
30
29
  <script>
31
- if (SC.setupBodyClassNames) SC.setupBodyClassNames() ;
30
+ if (window.SC && SC.setupBodyClassNames) SC.setupBodyClassNames() ;
32
31
  </script>
33
32
 
34
33
  <% #