sproutcore 0.9.10 → 0.9.11

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 (42) hide show
  1. data/History.txt +25 -0
  2. data/Manifest.txt +2 -1
  3. data/bin/sc-server +4 -1
  4. data/frameworks/sproutcore/HISTORY +75 -3
  5. data/frameworks/sproutcore/{Core.js → core.js} +2 -3
  6. data/frameworks/sproutcore/drag/drag.js +1 -1
  7. data/frameworks/sproutcore/english.lproj/buttons.css +3 -2
  8. data/frameworks/sproutcore/english.lproj/detect-browser +44 -0
  9. data/frameworks/sproutcore/foundation/animator.js +40 -40
  10. data/frameworks/sproutcore/foundation/application.js +1 -1
  11. data/frameworks/sproutcore/foundation/benchmark.js +2 -2
  12. data/frameworks/sproutcore/foundation/error.js +61 -16
  13. data/frameworks/sproutcore/foundation/input_manager.js +1 -1
  14. data/frameworks/sproutcore/foundation/mock.js +1 -1
  15. data/frameworks/sproutcore/foundation/node_descriptor.js +2 -2
  16. data/frameworks/sproutcore/foundation/object.js +1 -1
  17. data/frameworks/sproutcore/foundation/path_module.js +1 -1
  18. data/frameworks/sproutcore/foundation/responder.js +1 -1
  19. data/frameworks/sproutcore/foundation/run_loop.js +1 -1
  20. data/frameworks/sproutcore/foundation/server.js +1 -1
  21. data/frameworks/sproutcore/foundation/string.js +32 -3
  22. data/frameworks/sproutcore/foundation/timer.js +1 -1
  23. data/frameworks/sproutcore/foundation/undo_manager.js +1 -1
  24. data/frameworks/sproutcore/globals/window.js +1 -1
  25. data/frameworks/sproutcore/lib/core_views.rb +1 -1
  26. data/frameworks/sproutcore/lib/index.rhtml +7 -1
  27. data/frameworks/sproutcore/mixins/observable.js +115 -7
  28. data/frameworks/sproutcore/models/record.js +1 -1
  29. data/frameworks/sproutcore/tests/views/view/innerFrame.rhtml +101 -99
  30. data/frameworks/sproutcore/views/collection/grid.js +1 -1
  31. data/frameworks/sproutcore/views/collection/table.js +1 -1
  32. data/frameworks/sproutcore/views/list_item.js +1 -1
  33. data/frameworks/sproutcore/views/progress.js +21 -11
  34. data/frameworks/sproutcore/views/segmented.js +40 -15
  35. data/lib/sproutcore/bundle.rb +3 -3
  36. data/lib/sproutcore/bundle_manifest.rb +7 -7
  37. data/lib/sproutcore/jsdoc.rb +4 -2
  38. data/lib/sproutcore/library.rb +112 -43
  39. data/lib/sproutcore/merb/bundle_controller.rb +77 -4
  40. data/lib/sproutcore/version.rb +1 -1
  41. data/sc_generators/client/templates/core.js +1 -4
  42. metadata +4 -3
@@ -3,7 +3,7 @@
3
3
  // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
- require('Core');
6
+ require('core');
7
7
  require('foundation/responder');
8
8
 
9
9
  /**
@@ -3,7 +3,7 @@
3
3
  // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
- require('Core') ;
6
+ require('core') ;
7
7
  require('foundation/date');
8
8
  require('foundation/string') ;
9
9
 
@@ -205,7 +205,7 @@ SC.Benchmark = {
205
205
  return ret ;
206
206
  },
207
207
 
208
- reset: function() { this.stats = {} ; debugger;},
208
+ reset: function() { this.stats = {} ; /*debugger;*/},
209
209
 
210
210
  // This is private, but it is used in some places, so we are keeping this for
211
211
  // compatibility.
@@ -5,15 +5,54 @@
5
5
 
6
6
  require('foundation/object');
7
7
 
8
- // Error is used to communicate errors throughout the app.
9
- SC.Error = SC.Object.extend({
10
- code: -1, // error code. Used to designate type.
11
- description: '', // human readable dscriptions.
12
- label: null // optionally set to human readable the name of the item with the error.
8
+ /**
9
+ @class
10
+
11
+ An error, used to represent an error state.
12
+
13
+ Many API's within SproutCore will return an instance of this object whenever
14
+ they have an error occur. An error includes an error code, description,
15
+ and optional human readable label that indicates the item that failed.
16
+
17
+ Depending on the error, other properties may also be added to the object
18
+ to help you recover from the failure.
19
+
20
+ You can pass error objects to various UI elements to display the error in
21
+ the interface. You can easily determine if the value returned by some API is
22
+ an error or not using the helper SC.$ok(value).
23
+
24
+ @extends SC.Object
25
+ @since SproutCore 1.0
26
+ */
27
+ SC.Error = SC.Object.extend(
28
+ /** @scope SC.Error.prototype */ {
29
+
30
+ /**
31
+ error code. Used to designate the error type.
32
+ */
33
+ code: -1,
34
+
35
+ /**
36
+ Human readable description of the error. This can also be a non-localized
37
+ key.
38
+ */
39
+ description: '',
40
+
41
+ /**
42
+ Human readable name of the item with the error.
43
+ */
44
+ label: null
13
45
  }) ;
14
46
 
15
- // this will create a new instance of the receiver with the passed
16
- // description, etc.
47
+ /**
48
+ Creates a new SC.Error instance with the passed description, label, and
49
+ code. All parameters are optional.
50
+
51
+ @param description {String} human readable description of the error
52
+ @param label {String} human readable name of the item with the error
53
+ @param code {Number} an error code to use for testing.
54
+ @returns {SC.Error} new error instance.
55
+ */
17
56
  SC.Error.desc = function(description, label, code) {
18
57
  var opts = { description: description } ;
19
58
  if (label !== undefined) opts.label = label ;
@@ -21,19 +60,25 @@ SC.Error.desc = function(description, label, code) {
21
60
  return this.create(opts) ;
22
61
  } ;
23
62
 
24
- // returns an error object.
25
- function $error(description, label, c) {
63
+ /**
64
+ Shorthand form of the SC.Error.desc method.
65
+ */
66
+ SC.$error = function(description, label, c) {
26
67
  return SC.Error.desc(description,label, c);
27
68
  } ;
69
+ var $error = SC.$error ; // export globally
28
70
 
29
-
30
- // returns true if the return value is not false or an error.
31
- function $ok(ret) {
71
+ /**
72
+ Returns YES if the passed value is an error object, otherwise NO.
73
+ */
74
+ SC.$ok = function(ret) {
32
75
  return (ret !== false) && ($type(ret) != T_ERROR) ;
33
- }
34
-
76
+ };
77
+ var $ok = SC.$ok ; // export globally.
35
78
 
36
79
  // STANDARD ERROR OBJECTS
37
80
 
38
- // Used by objects that do not support multiple values.
39
- SC.Error.HAS_MULTIPLE_VALUES = -100 ;
81
+ /**
82
+ Standard error code for errors that do not support multiple values.
83
+ */
84
+ SC.Error.HAS_MULTIPLE_VALUES = -100 ;
@@ -3,7 +3,7 @@
3
3
  // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
- require('Core') ;
6
+ require('core') ;
7
7
  require('foundation/object') ;
8
8
 
9
9
  /** @class
@@ -1,4 +1,4 @@
1
- require('Core');
1
+ require('core');
2
2
  require('foundation/object');
3
3
 
4
4
  /**
@@ -3,7 +3,7 @@
3
3
  // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
- require('Core') ;
6
+ require('core') ;
7
7
 
8
8
  /**
9
9
  This object can generate HTML DOM elements from a hash-based description of
@@ -55,5 +55,5 @@ SC.NodeDescriptor = {
55
55
  },
56
56
 
57
57
  ignoredProperties: ['tag','cssClass','id','style','childNodes','innerHTML']
58
- }
58
+ };
59
59
 
@@ -3,7 +3,7 @@
3
3
  // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
- require('Core') ;
6
+ require('core') ;
7
7
  require('foundation/benchmark') ;
8
8
  require('mixins/observable') ;
9
9
  require('mixins/array') ;
@@ -12,7 +12,7 @@
12
12
  //
13
13
  // ==========================================================================
14
14
 
15
- require('Core') ;
15
+ require('core') ;
16
16
  require('foundation/benchmark') ;
17
17
 
18
18
  // Constants
@@ -3,7 +3,7 @@
3
3
  // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
- require('Core') ;
6
+ require('core') ;
7
7
  require('foundation/object') ;
8
8
  require('foundation/input_manager');
9
9
 
@@ -3,7 +3,7 @@
3
3
  // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
- require('Core') ;
6
+ require('core') ;
7
7
 
8
8
  /**
9
9
  @class
@@ -3,7 +3,7 @@
3
3
  // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
- require('Core') ;
6
+ require('core') ;
7
7
 
8
8
  // The Server object knows how to send requests to the server and how to
9
9
  // get things back from the server. It automatically handles situations
@@ -154,8 +154,15 @@ Object.extend(String,
154
154
  var ret = (this.useAutodetectedLanguage) ? (this.browserLanguage || this.preferredLanguage || 'en') : (this.preferredLanguage || this.browserLanguage || 'en') ;
155
155
 
156
156
  // then try a couple of normalized forms...
157
- if (!this[ret]) switch(ret)
158
- {
157
+ if (!this[ret]) ret = this.normalizedLanguage(ret);
158
+ return ret ;
159
+ },
160
+
161
+ /**
162
+ Returns a normalized language string for the two letter country code.
163
+ */
164
+ normalizedLanguage: function(ret) {
165
+ switch(ret) {
159
166
  case 'fr':
160
167
  ret = 'French';
161
168
  break ;
@@ -170,11 +177,33 @@ Object.extend(String,
170
177
  ret = 'English' ;
171
178
  break ;
172
179
 
180
+ case 'es':
181
+ ret = 'Spanish' ;
182
+ break;
183
+
173
184
  default:
174
185
  break ;
175
186
  }
187
+ return ret;
188
+ },
189
+
190
+ /**
191
+ Adds loc strings for the named language. This method takes care of
192
+ creating the localized string hash if it does not already exist.
193
+ The language can be one of the following or any two-letter country code.
176
194
 
177
- return ret ;
195
+ English, French, German, Japanese, Spanish
196
+
197
+ @param language {String} the language code
198
+ @param strings {Hash} hash of loc strings.
199
+ @returns {this}
200
+ */
201
+ addStringsFor: function(language, strings) {
202
+ // convert language to a normalized name...
203
+ language = String.normalizedLanguage(language) ;
204
+ if (!String[language]) String[language] = {} ;
205
+ Object.extend(String[language], strings || {});
206
+ return this;
178
207
  }
179
208
 
180
209
  });
@@ -3,7 +3,7 @@
3
3
  // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
- require('Core') ;
6
+ require('core') ;
7
7
  require('foundation/object');
8
8
 
9
9
  /**
@@ -3,7 +3,7 @@
3
3
  // copyright 2006-2008, Sprout Systems, Inc. and contributors.
4
4
  // ==========================================================================
5
5
 
6
- require('Core');
6
+ require('core');
7
7
 
8
8
  /**
9
9
  @class
@@ -3,7 +3,7 @@
3
3
  // copyright 2006-2008 Sprout Systems, Inc.
4
4
  // ========================================================================
5
5
 
6
- require('Core') ;
6
+ require('core') ;
7
7
  require('foundation/responder');
8
8
  require('panes/pane');
9
9
 
@@ -195,7 +195,7 @@ view_helper :image_view do
195
195
  property :value
196
196
 
197
197
  attribute :src, static_url('blank')
198
-
198
+ attribute :alt, ''
199
199
  var :tag, 'img'
200
200
  css_class_names << 'sc-image-view'
201
201
  end
@@ -21,10 +21,16 @@
21
21
  # stylesheets, you don't need to change it here. Instead, use the
22
22
  # :requires option in routes.rb.
23
23
  -%>
24
+ <script src="<%= static_url('detect-browser') %>" type="text/javascript"></script>
25
+
24
26
  <%= stylesheets_for_client %>
25
27
  <%= @content_for_page_styles %>
26
28
  </head>
27
- <body class="<%= @theme || 'sc-theme' %> focus">
29
+ <body class="<%= @theme || 'sc-theme' %> focus">
30
+ <script>
31
+ if (SC.setupBodyClassNames) SC.setupBodyClassNames() ;
32
+ </script>
33
+
28
34
  <% #
29
35
  # This is where you root body element will appear. To cause your
30
36
  # content to appear here, just declare content_for('body') in one of
@@ -518,7 +518,6 @@ SC.Observable = {
518
518
  Adds an observer on a property.
519
519
 
520
520
  This is the core method used to register an observer for a property.
521
- The observer can be either a simple function or an object and a method.
522
521
 
523
522
  Once you call this method, anytime the key's value is set, your observer
524
523
  will be notified. Note that the observers are triggered anytime the
@@ -526,9 +525,8 @@ SC.Observable = {
526
525
  observer should be prepared to handle that.
527
526
 
528
527
  @param key {String} the key to observer
529
- @param target {Object} the object holding the action to call. May benull.
530
- @param action {String,Function} the action to call.
531
- @returns {void}
528
+ @param func {String} the function to call when the key changes.
529
+ @returns {SC.Object}
532
530
  */
533
531
  addObserver: function(key,func) {
534
532
  var kvo = this._kvo() ;
@@ -550,6 +548,8 @@ SC.Observable = {
550
548
  while(!found && --loc >= 0) found = (observers[loc] == func) ;
551
549
  if (!found) observers.push(func) ;
552
550
  }
551
+
552
+ return this;
553
553
 
554
554
  },
555
555
 
@@ -573,6 +573,8 @@ SC.Observable = {
573
573
  observers = observers.without(func) ;
574
574
  kvo.observers[key] = observers ;
575
575
  }
576
+
577
+ return this;
576
578
  },
577
579
 
578
580
  addProbe: function(key) { this.addObserver(key,logChange); },
@@ -745,10 +747,116 @@ SC.Observable = {
745
747
  // FUNCTION ENHANCEMENTS
746
748
  //
747
749
  // Enhance function.
748
- Object.extend(Function.prototype,{
750
+ Object.extend(Function.prototype,
751
+ /** @scope Function.prototype */ {
749
752
 
750
- // Declare a function as a property. This makes it something that can be
751
- // accessed via get/set.
753
+ /**
754
+ Indicates that the function should be treated as a computed property.
755
+
756
+ Computed properties are methods that you want to treat as if they were
757
+ static properties. When you use get() or set() on a computed property,
758
+ the object will call the property method and return its value instead of
759
+ returning the method itself. This makes it easy to create "virtual
760
+ properties" that are computed dynamically from other properties.
761
+
762
+ Consider the following example:
763
+
764
+ {{{
765
+ contact = SC.Object.create({
766
+
767
+ firstName: "Charles",
768
+ lastName: "Jolley",
769
+
770
+ // This is a computed property!
771
+ fullName: function() {
772
+ return this.getEach('firstName','lastName').compact().join(' ') ;
773
+ }.property('firstName', 'lastName'),
774
+
775
+ // this is not
776
+ getFullName: function() {
777
+ return this.getEach('firstName','lastName').compact().join(' ') ;
778
+ }
779
+ });
780
+
781
+ contact.get('firstName') ;
782
+ --> "Charles"
783
+
784
+ contact.get('fullName') ;
785
+ --> "Charles Jolley"
786
+
787
+ contact.get('getFullName') ;
788
+ --> function()
789
+ }}}
790
+
791
+ Note that when you get the fullName property, SproutCore will call the
792
+ fullName() function and return its value whereas when you get() a property
793
+ that contains a regular method (such as getFullName above), then the
794
+ function itself will be returned instead.
795
+
796
+ h2. Using Dependent Keys
797
+
798
+ Computed properties are often computed dynamically from other member
799
+ properties. Whenever those properties change, you need to notify any
800
+ object that is observing the computed property that the computed property
801
+ has changed also. We call these properties the computed property is based
802
+ upon "dependent keys".
803
+
804
+ For example, in the contact object above, the fullName property depends on
805
+ the firstName and lastName property. If either property value changes,
806
+ any observer watching the fullName property will need to be notified as
807
+ well.
808
+
809
+ You inform SproutCore of these dependent keys by passing the key names
810
+ as parameters to the property() function. Whenever the value of any key
811
+ you name here changes, the computed property will be marked as changed
812
+ also.
813
+
814
+ You should always register dependent keys for computed properties to
815
+ ensure they update.
816
+
817
+ h2. Using Computed Properties as Setters
818
+
819
+ Computed properties can be used to modify the state of an object as well
820
+ as to return a value. Unlike many other key-value system, you use the
821
+ same method to both get and set values on a computed property. To
822
+ write a setter, simply declare two extra parameters: key and value.
823
+
824
+ Whenever your property function is called as a setter, the value
825
+ parameter will be set. Whenever your property is called as a getter the
826
+ value parameter will be undefined.
827
+
828
+ For example, the following object will split any full name that you set
829
+ into a first name and last name components and save them.
830
+
831
+ {{{
832
+ contact = SC.Object.create({
833
+
834
+ fullName: function(key, value) {
835
+ if (value !== undefined) {
836
+ var parts = value.split(' ') ;
837
+ this.beginPropertyChanges()
838
+ .set('firstName', parts[0])
839
+ .set('lastName', parts[1])
840
+ .endPropertyChanges() ;
841
+ }
842
+ return this.getEach('firstName', 'lastName').compact().join(' ');
843
+ }.property('firstName','lastName')
844
+
845
+ }) ;
846
+
847
+ }}}
848
+
849
+ bq. *Why Use The Same Method for Getters and Setters?* Most property-
850
+ based frameworks expect you to write two methods for each property but
851
+ SproutCore only uses one. We do this because most of the time when
852
+ you write a setter is is basically a getter plus some extra work. There
853
+ is little added benefit in writing both methods when you can conditionally
854
+ exclude part of it. This helps to keep your code more compact and easier
855
+ to maintain.
856
+
857
+ @param dependentKeys {String...} optional set of dependent keys
858
+ @returns {Function} the declared function instance
859
+ */
752
860
  property: function() {
753
861
  this.dependentKeys = $A(arguments) ;
754
862
  this.isProperty = true; return this;