sproutcore 0.9.14 → 0.9.15
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 +43 -0
- data/Manifest.txt +12 -3
- data/bin/sc-build +19 -3
- data/bin/sc-install +5 -0
- data/bin/sc-remove +5 -0
- data/bin/sc-update +5 -0
- data/frameworks/prototype/prototype.js +267 -230
- data/frameworks/sproutcore/HISTORY +281 -135
- data/frameworks/sproutcore/controllers/array.js +133 -22
- data/frameworks/sproutcore/controllers/collection.js +4 -5
- data/frameworks/sproutcore/controllers/object.js +8 -2
- data/frameworks/sproutcore/core.js +361 -159
- data/frameworks/sproutcore/{foundation → debug}/unittest.js +3 -3
- data/frameworks/sproutcore/english.lproj/detect-browser +1 -1
- data/frameworks/sproutcore/english.lproj/theme.css +2 -2
- data/frameworks/sproutcore/foundation/application.js +6 -1
- data/frameworks/sproutcore/foundation/benchmark.js +37 -11
- data/frameworks/sproutcore/foundation/date.js +1 -1
- data/frameworks/sproutcore/foundation/enumerator.js +105 -0
- data/frameworks/sproutcore/foundation/object.js +19 -20
- data/frameworks/sproutcore/foundation/responder.js +1 -1
- data/frameworks/sproutcore/foundation/set.js +164 -57
- data/frameworks/sproutcore/foundation/string.js +151 -47
- data/frameworks/sproutcore/foundation/utils.js +84 -3
- data/frameworks/sproutcore/lib/collection_view.rb +1 -0
- data/frameworks/sproutcore/license.js +28 -0
- data/frameworks/sproutcore/mixins/array.js +73 -209
- data/frameworks/sproutcore/mixins/delegate_support.js +1 -1
- data/frameworks/sproutcore/mixins/enumerable.js +1006 -0
- data/frameworks/sproutcore/mixins/observable.js +153 -84
- data/frameworks/sproutcore/mixins/selection_support.js +13 -1
- data/frameworks/sproutcore/models/record.js +74 -27
- data/frameworks/sproutcore/models/store.js +7 -3
- data/frameworks/sproutcore/server/rails_server.js +82 -0
- data/frameworks/sproutcore/server/rest_server.js +178 -0
- data/frameworks/sproutcore/{foundation → server}/server.js +101 -48
- data/frameworks/sproutcore/tests/core/guidFor.rhtml +114 -0
- data/frameworks/sproutcore/tests/foundation/array.rhtml +6 -7
- data/frameworks/sproutcore/tests/foundation/set.rhtml +254 -0
- data/frameworks/sproutcore/tests/mixins/enumerable.rhtml +421 -0
- data/frameworks/sproutcore/tests/mixins/observable.rhtml +127 -0
- data/frameworks/sproutcore/tests/models/model.rhtml +23 -22
- data/frameworks/sproutcore/tests/views/collection/incremental_rendering.rhtml +2 -2
- data/frameworks/sproutcore/tests/views/view/clippingFrame.rhtml +112 -109
- data/frameworks/sproutcore/tests/views/view/frame.rhtml +91 -88
- data/frameworks/sproutcore/validators/date.js +1 -7
- data/frameworks/sproutcore/views/collection/collection.js +7 -2
- data/frameworks/sproutcore/views/list_item.js +141 -3
- data/frameworks/sproutcore/views/split.js +14 -11
- data/frameworks/sproutcore/views/view.js +9 -6
- data/lib/sproutcore/build_tools/html_builder.rb +19 -3
- data/lib/sproutcore/build_tools/resource_builder.rb +9 -3
- data/lib/sproutcore/bundle.rb +21 -0
- data/lib/sproutcore/bundle_manifest.rb +64 -20
- data/lib/sproutcore/helpers/capture_helper.rb +2 -2
- data/lib/sproutcore/library.rb +33 -9
- data/lib/sproutcore/merb/bundle_controller.rb +16 -5
- data/lib/sproutcore/version.rb +1 -1
- data/lib/sproutcore/view_helpers.rb +1 -1
- data/{sc-config.rb → sc-config} +5 -2
- metadata +24 -5
@@ -5,30 +5,47 @@
|
|
5
5
|
|
6
6
|
// These are basic enhancements to the string class used throughout
|
7
7
|
// SproutCore.
|
8
|
-
// capitalize a string.
|
9
|
-
Object.extend(String.prototype,{
|
10
|
-
|
11
|
-
// Capitalize a string.
|
12
|
-
//
|
13
|
-
// mode: optional. 'each' - capitalize each word. the default.
|
14
|
-
// 'first' - capitalize the first word only.
|
15
|
-
|
16
|
-
capitalize: function(mode) {
|
17
|
-
var words = (mode == 'first') ? this : this.split(' ') ;
|
18
|
-
words = words.map(function(word) {
|
19
|
-
if (word.length == 0) return word ;
|
20
|
-
return word.charAt(0).toUpperCase() + word.substring(1) ;
|
21
|
-
}) ;
|
22
|
-
return words.join(' ') ;
|
23
|
-
},
|
24
8
|
|
9
|
+
SC.STRING_TITLEIZE_REGEXP = (/([\s|\-|\_|\n])([^\s|\-|\_|\n]?)/g);
|
10
|
+
|
11
|
+
/**
|
12
|
+
@namespace
|
13
|
+
|
14
|
+
SproutCore implements a variety of enhancements to the built-in String
|
15
|
+
object that make it easy to perform common substitutions and conversions.
|
16
|
+
|
17
|
+
Most of the utility methods defined here mirror those found in Prototype
|
18
|
+
1.6.
|
19
|
+
|
20
|
+
@since SproutCore 1.0
|
21
|
+
*/
|
22
|
+
SC.String = {
|
23
|
+
|
25
24
|
// Interpolate string. looks for %@ or %@1; to control the order of params.
|
26
|
-
|
27
|
-
|
25
|
+
/**
|
26
|
+
Apply formatting options to the string. This will look for occurrences
|
27
|
+
of %@ in your string and substitute them with the arguments you pass into
|
28
|
+
this method. If you want to control the specific order of replacement,
|
29
|
+
you can add a number after the key as well to indicate which argument
|
30
|
+
you want to insert.
|
31
|
+
|
32
|
+
Ordered insertions are most useful when building loc strings where values
|
33
|
+
you need to insert may appear in different orders.
|
34
|
+
|
35
|
+
h3. Examples
|
28
36
|
|
37
|
+
{{{
|
38
|
+
"Hello %@ %@".fmt('John', 'Doe') => "Hello John Doe"
|
39
|
+
"Hello %@2, %@1".fmt('John', 'Doe') => "Hello Doe, John"
|
40
|
+
}}}
|
41
|
+
|
42
|
+
@param args {Object...} optional arguments
|
43
|
+
@returns {String} formatted string
|
44
|
+
*/
|
45
|
+
fmt: function() {
|
29
46
|
// first, replace any ORDERED replacements.
|
30
47
|
var str = this.gsub(/%@([0-9]+)/, function(m) {
|
31
|
-
return (
|
48
|
+
return (arguments[parseInt(m[1],0)-1] || '').toString();
|
32
49
|
}) ;
|
33
50
|
|
34
51
|
// now, replace any remaining %@ items. Use this indexOf() method b/c
|
@@ -36,13 +53,14 @@ Object.extend(String.prototype,{
|
|
36
53
|
var ret = [] ;
|
37
54
|
var idx = -1 ;
|
38
55
|
var loc = 0 ;
|
56
|
+
var argIdx = 0;
|
39
57
|
while((idx = str.indexOf("%@",loc)) >= 0) {
|
40
58
|
// slice off initial part of string and push into ret. update loc.
|
41
59
|
ret.push(str.slice(loc,idx)) ;
|
42
60
|
loc = idx + 2 ; // 2 to skip '%@'.
|
43
61
|
|
44
62
|
// add in replacement.
|
45
|
-
var value =
|
63
|
+
var value = arguments[argIdx++] ;
|
46
64
|
if (value && value.toString) value = value.toString() ;
|
47
65
|
ret.push(value) ;
|
48
66
|
}
|
@@ -56,8 +74,15 @@ Object.extend(String.prototype,{
|
|
56
74
|
return (ret.length > 1) ? ret.join('') : ret[0] ;
|
57
75
|
},
|
58
76
|
|
59
|
-
|
60
|
-
|
77
|
+
/**
|
78
|
+
Localizes the string. This will look up the reciever string as a key
|
79
|
+
in the current Strings hash. If the key matches, the loc'd value will be
|
80
|
+
used. The resulting string will also be passed through fmt() to insert
|
81
|
+
any variables.
|
82
|
+
|
83
|
+
@param args {Object...} optional arguments to interpolate also
|
84
|
+
@returns {String} the localized and formatted string.
|
85
|
+
*/
|
61
86
|
loc: function() {
|
62
87
|
// NB: This could be implemented as a wrapper to locWithDefault() but
|
63
88
|
// it would add some overhead to deal with the arguments and adds stack
|
@@ -66,60 +91,139 @@ Object.extend(String.prototype,{
|
|
66
91
|
var kit = String[String.currentLanguage()];
|
67
92
|
var str = kit[this] ;
|
68
93
|
if (!str) str = String.English[this] || this ;
|
69
|
-
return str.
|
94
|
+
return str.fmt.apply(str,arguments) ;
|
70
95
|
},
|
71
|
-
|
72
|
-
|
73
|
-
|
96
|
+
|
97
|
+
/**
|
98
|
+
Works just like loc() except that it will return the passed default
|
99
|
+
string if a matching key is not found.
|
100
|
+
|
101
|
+
@param def {String} the default to return
|
102
|
+
@param args {Object...} optional formatting arguments
|
103
|
+
@returns {String} localized and formatted string
|
104
|
+
*/
|
74
105
|
locWithDefault: function(def) {
|
75
106
|
var kit = String[String.currentLanguage()];
|
76
107
|
var str = kit[this] ;
|
77
108
|
if (!str) str = String.English[this] || def ;
|
78
|
-
var args =
|
109
|
+
var args = SC.$A(arguments) ;
|
79
110
|
args.shift() ; // escape def.
|
80
|
-
return str.
|
111
|
+
return str.fmt.apply(str, args) ;
|
112
|
+
},
|
113
|
+
|
114
|
+
/**
|
115
|
+
Capitalizes a string.
|
116
|
+
@return {String} capitalized string
|
117
|
+
*/
|
118
|
+
capitalize: function() {
|
119
|
+
return this.charAt(0).toUpperCase() + this.substring(1) ;
|
120
|
+
},
|
121
|
+
|
122
|
+
/**
|
123
|
+
Capitalized every word in the string, separated by spaces or dashes.
|
124
|
+
@return {String} titleized string.
|
125
|
+
*/
|
126
|
+
titleize: function() {
|
127
|
+
return this.replace(SC.STRING_TITLEIZE_REGEXP,
|
128
|
+
function(str,separater,character) {
|
129
|
+
return (character) ? (' ' + character.toUpperCase()) : ' ';
|
130
|
+
}).capitalize() ;
|
131
|
+
},
|
132
|
+
|
133
|
+
/**
|
134
|
+
Camelizes a string. This will take any words separated by spaces, dashes
|
135
|
+
or underscores and convert them into camelCase.
|
136
|
+
|
137
|
+
h3. Examples
|
138
|
+
|
139
|
+
{{{
|
140
|
+
"my favorite items".camelize() => "myFavoriteItems"
|
141
|
+
"css-class-name".camelize() => "cssClassName"
|
142
|
+
"action_name".camelize() => "actionName"
|
143
|
+
}}}
|
144
|
+
|
145
|
+
@returns {String} camelized string
|
146
|
+
*/
|
147
|
+
camelize: function() {
|
148
|
+
var parts = this.split('-'), len = parts.length;
|
149
|
+
if (len == 1) return parts[0];
|
150
|
+
|
151
|
+
var camelized = this.charAt(0) == '-'
|
152
|
+
? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
|
153
|
+
: parts[0];
|
154
|
+
|
155
|
+
for (var i = 1; i < len; i++)
|
156
|
+
camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
|
157
|
+
|
158
|
+
return camelized;
|
81
159
|
},
|
160
|
+
|
82
161
|
|
162
|
+
/**
|
163
|
+
Converts the string into a class name. This method will camelize your
|
164
|
+
string and then capitalize the first letter.
|
165
|
+
*/
|
83
166
|
classify: function() {
|
84
167
|
return this.camelize().capitalize() ;
|
85
168
|
},
|
86
169
|
|
170
|
+
/**
|
171
|
+
Converts a camelized string into all lower case separated by underscores.
|
172
|
+
|
173
|
+
@returns {String} the decamelized string.
|
174
|
+
*/
|
87
175
|
decamelize: function() {
|
88
176
|
return this.replace(/([a-z])([A-Z])/g,'$1_$2').toLowerCase();
|
89
177
|
},
|
90
178
|
|
179
|
+
/**
|
180
|
+
Converts a camelized string or a string with spaces or underscores into
|
181
|
+
a string with components separated by dashes.
|
182
|
+
|
183
|
+
@returns {String} the dasherized string.
|
184
|
+
*/
|
91
185
|
dasherize: function() {
|
92
186
|
return this.decamelize().replace(/[ _]/g,'-') ;
|
93
187
|
},
|
94
188
|
|
189
|
+
/**
|
190
|
+
Converts a camelized string or a string with dashes or underscores into
|
191
|
+
a string with components separated by spaces.
|
192
|
+
|
193
|
+
@returns {String} the humanized string.
|
194
|
+
*/
|
95
195
|
humanize: function() {
|
96
196
|
return this.decamelize().replace(/[-_]/g,' ') ;
|
97
197
|
},
|
98
198
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
}
|
105
|
-
|
106
|
-
|
107
|
-
},
|
108
|
-
|
109
|
-
trim: function ()
|
110
|
-
{
|
199
|
+
/**
|
200
|
+
Removes any extra whitespace from the edges of the strings.
|
201
|
+
|
202
|
+
This method is also aliased as strip().
|
203
|
+
|
204
|
+
@returns {String} the trimmed string
|
205
|
+
*/
|
206
|
+
trim: function () {
|
111
207
|
return this.replace(/^\s+|\s+$/g,"");
|
112
208
|
},
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
209
|
+
|
210
|
+
/**
|
211
|
+
Explodes a string into an array of characters.
|
212
|
+
|
213
|
+
@returns {Array}
|
214
|
+
*/
|
215
|
+
toArray: function() {
|
216
|
+
return this.split('');
|
117
217
|
}
|
118
218
|
|
119
|
-
}
|
219
|
+
} ;
|
220
|
+
|
221
|
+
// Deprecated, longer version of this method.
|
222
|
+
SC.String.format = SC.String.fmt;
|
223
|
+
SC.String.strip = SC.String.trim; // convenience alias.
|
120
224
|
|
121
|
-
//
|
122
|
-
String.prototype.
|
225
|
+
// Apply SC.String mixin to built-in String object
|
226
|
+
SC.mixin(String.prototype, SC.String) ;
|
123
227
|
|
124
228
|
// Add strings for various languages to this collection. String.loc()
|
125
229
|
// method will try to localize the string passed using the current language.
|
@@ -6,10 +6,75 @@
|
|
6
6
|
// These are helpful utility functions for calculating range and rect values
|
7
7
|
|
8
8
|
|
9
|
-
|
9
|
+
SC.mixin(
|
10
10
|
/** @scope SC */
|
11
11
|
{
|
12
12
|
|
13
|
+
_downloadFrames: 0, // count of download frames inserted into document
|
14
|
+
|
15
|
+
/**
|
16
|
+
Starts a download of the file at the named path.
|
17
|
+
|
18
|
+
Use this method when you want to cause a file to be downloaded to a users
|
19
|
+
desktop instead of having it display in the web browser. Note that your
|
20
|
+
server must return a header indicating that the file is intended for
|
21
|
+
download also.
|
22
|
+
*/
|
23
|
+
download: function(path) {
|
24
|
+
var tempDLIFrame=document.createElement('iframe');
|
25
|
+
var frameId = 'DownloadFrame_' + this._downloadFrames;
|
26
|
+
tempDLIFrame.setAttribute('id',frameId);
|
27
|
+
tempDLIFrame.style.border='10px';
|
28
|
+
tempDLIFrame.style.width='0px';
|
29
|
+
tempDLIFrame.style.height='0px';
|
30
|
+
tempDLIFrame.style.position='absolute';
|
31
|
+
tempDLIFrame.style.top='-10000px';
|
32
|
+
tempDLIFrame.style.left='-10000px';
|
33
|
+
// Don't set the iFrame content yet if this is Safari
|
34
|
+
if (!(SC.isSafari())) {
|
35
|
+
tempDLIFrame.setAttribute('src',path);
|
36
|
+
}
|
37
|
+
document.getElementsByTagName('body')[0].appendChild(tempDLIFrame);
|
38
|
+
if (SC.isSafari()) {
|
39
|
+
tempDLIFrame.setAttribute('src',path);
|
40
|
+
}
|
41
|
+
this._downloadFrames = this._downloadFrames + 1;
|
42
|
+
if (!(SC.isSafari())) {
|
43
|
+
var r = function() {
|
44
|
+
document.body.removeChild(document.getElementById(frameId));
|
45
|
+
frameId = null;
|
46
|
+
} ;
|
47
|
+
var t = r.invokeLater(null, 2000);
|
48
|
+
}
|
49
|
+
//remove possible IE7 leak
|
50
|
+
tempDLIFrame = null;
|
51
|
+
},
|
52
|
+
|
53
|
+
/**
|
54
|
+
Takes a URL of any type and normalizes it into a fully qualified URL with
|
55
|
+
hostname. For example:
|
56
|
+
|
57
|
+
{{{
|
58
|
+
"some/path" => "http://localhost:4020/some/path"
|
59
|
+
"/some/path" => "http://localhost:4020/some/path"
|
60
|
+
"http://localhost:4020/some/path" => "http://localhost:4020/some/path"
|
61
|
+
}}}
|
62
|
+
|
63
|
+
@param url {String} the URL
|
64
|
+
@returns {String} the normalized URL
|
65
|
+
*/
|
66
|
+
normalizeURL: function(url) {
|
67
|
+
if (url.slice(0,1) == '/') {
|
68
|
+
url = window.location.protocol + '//' + window.location.host + url ;
|
69
|
+
} else if ((url.slice(0,5) == 'http:') || (url.slice(0,6) == 'https:')) {
|
70
|
+
// no change
|
71
|
+
} else {
|
72
|
+
url = window.location.href + '/' + url ;
|
73
|
+
}
|
74
|
+
return url ;
|
75
|
+
},
|
76
|
+
|
77
|
+
|
13
78
|
/** Return the left edge of the frame */
|
14
79
|
minX: function(frame) {
|
15
80
|
return frame.x;
|
@@ -142,9 +207,17 @@ Object.extend(SC,
|
|
142
207
|
|
143
208
|
// add up all the offsets for the element.
|
144
209
|
var element = el ;
|
210
|
+
var isFirefox3 = SC.Platform.Firefox >= 3 ;
|
145
211
|
while (element) {
|
146
|
-
valueT += (element.offsetTop || 0)
|
147
|
-
|
212
|
+
valueT += (element.offsetTop || 0);
|
213
|
+
if (!isFirefox3 || (element !== el)) {
|
214
|
+
valueT += (element.clientTop || 0);
|
215
|
+
}
|
216
|
+
|
217
|
+
valueL += (element.offsetLeft || 0);
|
218
|
+
if (!isFirefox3 || (element !== el)) {
|
219
|
+
valueL += (element.clientLeft || 0);
|
220
|
+
}
|
148
221
|
|
149
222
|
// bizarely for FireFox if your offsetParent has a border, then it can
|
150
223
|
// impact the offset.
|
@@ -158,6 +231,14 @@ Object.extend(SC,
|
|
158
231
|
}
|
159
232
|
valueL += left; valueT += top ;
|
160
233
|
}
|
234
|
+
|
235
|
+
// In FireFox 3 -- the offsetTop/offsetLeft subtracts the clientTop/
|
236
|
+
// clientLeft of the offset parent.
|
237
|
+
var offsetParent = element.offsetParent ;
|
238
|
+
if ((SC.Platform.Firefox >= 3) && offsetParent) {
|
239
|
+
valueT -= offsetParent.clientTop ;
|
240
|
+
valueL -= offsetParent.clientLeft;
|
241
|
+
}
|
161
242
|
}
|
162
243
|
|
163
244
|
// Safari fix
|
@@ -32,6 +32,7 @@ view_helper :collection_view do
|
|
32
32
|
property :can_delete_content
|
33
33
|
|
34
34
|
property :content_icon_key
|
35
|
+
property :content_checkbox_key
|
35
36
|
|
36
37
|
# Unless the developer passes something specific, automatically enable
|
37
38
|
# has_content_icon if either icon property is specified.
|
@@ -0,0 +1,28 @@
|
|
1
|
+
//@license
|
2
|
+
// ==========================================================================
|
3
|
+
// SproutCore -- JavaScript Application Framework
|
4
|
+
// copyright 2006-2008, Sprout Systems, Inc. and contributors.
|
5
|
+
//
|
6
|
+
// Permission is hereby granted, free of charge, to any person obtaining a
|
7
|
+
// copy of this software and associated documentation files (the "Software"),
|
8
|
+
// to deal in the Software without restriction, including without limitation
|
9
|
+
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
10
|
+
// and/or sell copies of the Software, and to permit persons to whom the
|
11
|
+
// Software is furnished to do so, subject to the following conditions:
|
12
|
+
//
|
13
|
+
// The above copyright notice and this permission notice shall be included in
|
14
|
+
// all copies or substantial portions of the Software.
|
15
|
+
//
|
16
|
+
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
21
|
+
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
22
|
+
// DEALINGS IN THE SOFTWARE.
|
23
|
+
//
|
24
|
+
// For more information about SproutCore, visit http://www.sproutcore.com
|
25
|
+
//
|
26
|
+
//
|
27
|
+
// ==========================================================================
|
28
|
+
//@license
|