sproutcore 0.9.10 → 0.9.11
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +25 -0
- data/Manifest.txt +2 -1
- data/bin/sc-server +4 -1
- data/frameworks/sproutcore/HISTORY +75 -3
- data/frameworks/sproutcore/{Core.js → core.js} +2 -3
- data/frameworks/sproutcore/drag/drag.js +1 -1
- data/frameworks/sproutcore/english.lproj/buttons.css +3 -2
- data/frameworks/sproutcore/english.lproj/detect-browser +44 -0
- data/frameworks/sproutcore/foundation/animator.js +40 -40
- data/frameworks/sproutcore/foundation/application.js +1 -1
- data/frameworks/sproutcore/foundation/benchmark.js +2 -2
- data/frameworks/sproutcore/foundation/error.js +61 -16
- data/frameworks/sproutcore/foundation/input_manager.js +1 -1
- data/frameworks/sproutcore/foundation/mock.js +1 -1
- data/frameworks/sproutcore/foundation/node_descriptor.js +2 -2
- data/frameworks/sproutcore/foundation/object.js +1 -1
- data/frameworks/sproutcore/foundation/path_module.js +1 -1
- data/frameworks/sproutcore/foundation/responder.js +1 -1
- data/frameworks/sproutcore/foundation/run_loop.js +1 -1
- data/frameworks/sproutcore/foundation/server.js +1 -1
- data/frameworks/sproutcore/foundation/string.js +32 -3
- data/frameworks/sproutcore/foundation/timer.js +1 -1
- data/frameworks/sproutcore/foundation/undo_manager.js +1 -1
- data/frameworks/sproutcore/globals/window.js +1 -1
- data/frameworks/sproutcore/lib/core_views.rb +1 -1
- data/frameworks/sproutcore/lib/index.rhtml +7 -1
- data/frameworks/sproutcore/mixins/observable.js +115 -7
- data/frameworks/sproutcore/models/record.js +1 -1
- data/frameworks/sproutcore/tests/views/view/innerFrame.rhtml +101 -99
- data/frameworks/sproutcore/views/collection/grid.js +1 -1
- data/frameworks/sproutcore/views/collection/table.js +1 -1
- data/frameworks/sproutcore/views/list_item.js +1 -1
- data/frameworks/sproutcore/views/progress.js +21 -11
- data/frameworks/sproutcore/views/segmented.js +40 -15
- data/lib/sproutcore/bundle.rb +3 -3
- data/lib/sproutcore/bundle_manifest.rb +7 -7
- data/lib/sproutcore/jsdoc.rb +4 -2
- data/lib/sproutcore/library.rb +112 -43
- data/lib/sproutcore/merb/bundle_controller.rb +77 -4
- data/lib/sproutcore/version.rb +1 -1
- data/sc_generators/client/templates/core.js +1 -4
- metadata +4 -3
@@ -3,7 +3,7 @@
|
|
3
3
|
// copyright 2006-2008 Sprout Systems, Inc.
|
4
4
|
// ========================================================================
|
5
5
|
|
6
|
-
require('
|
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
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
|
-
|
16
|
-
|
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
|
-
|
25
|
-
|
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
|
-
|
31
|
-
|
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
|
-
|
39
|
-
|
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('
|
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('
|
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])
|
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
|
-
|
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
|
});
|
@@ -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
|
530
|
-
@
|
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
|
-
|
751
|
-
|
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;
|