sproutcore 1.9.0 → 1.9.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (24) hide show
  1. data/VERSION.yml +1 -1
  2. data/lib/frameworks/sproutcore/CHANGELOG.md +123 -1
  3. data/lib/frameworks/sproutcore/frameworks/ajax/system/request.js +13 -9
  4. data/lib/frameworks/sproutcore/frameworks/ajax/tests/system/request.js +68 -0
  5. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/locale.js +59 -60
  6. data/lib/frameworks/sproutcore/frameworks/core_foundation/system/selection_set.js +6 -4
  7. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/locale.js +48 -29
  8. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/selection_set/remove.js +53 -17
  9. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/destroy.js +34 -0
  10. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/destroyLayer.js +47 -11
  11. data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/views/view/viewDidResize.js +31 -36
  12. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view.js +10 -10
  13. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +55 -23
  14. data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/manipulation.js +1 -1
  15. data/lib/frameworks/sproutcore/frameworks/datastore/models/record.js +5 -1
  16. data/lib/frameworks/sproutcore/frameworks/datastore/system/nested_store.js +105 -105
  17. data/lib/frameworks/sproutcore/frameworks/datastore/tests/system/nested_store/commitChanges.js +131 -30
  18. data/lib/frameworks/sproutcore/frameworks/desktop/panes/menu.js +1 -0
  19. data/lib/frameworks/sproutcore/frameworks/foundation/system/utils/string_measurement.js +3 -2
  20. data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
  21. data/lib/frameworks/sproutcore/frameworks/runtime/system/string.js +9 -5
  22. data/lib/sproutcore/helpers/minifier.rb +0 -2
  23. data/lib/sproutcore/rack/filesystem.rb +5 -5
  24. metadata +3 -2
data/VERSION.yml CHANGED
@@ -1,4 +1,4 @@
1
1
  ---
2
2
  :major: 1
3
3
  :minor: 9
4
- :patch: 0
4
+ :patch: 1
@@ -1,11 +1,133 @@
1
1
  CHANGE LOG
2
2
  ==========
3
3
 
4
- 1.9.0
4
+ Edge
5
5
  ----------
6
6
 
7
7
  ### CHANGES & FEATURES
8
8
 
9
+ * Improves and adds documentation.
10
+ * Adds SC.appCache and SC.platform.supportsApplicationCache.
11
+ Working with the application cache is a confusing and time-consuming task.
12
+ This simple object abstracts out the most important properties for developers
13
+ to use: hasNewVersion, isNewVersionValid, progress and isReadyForOffline all
14
+ the while using the minimum number of event listeners which are properly
15
+ cleaned up when unneeded. It also has a property shouldPoll that will lazily
16
+ look for updates in the background at a fixed interval. This could be
17
+ especially useful in a test environment, where you want to ensure that the
18
+ testers aren't running the old version (which happens frequently when using
19
+ the application cache).
20
+ * Improves the center calculation for view layouts. Previously you could not use
21
+ a % width or height with a center value, but there is no technical reason for
22
+ this limitation. For example, a view with width: 0.3% and centerX: 0, should
23
+ get the layout style: "width: 30%; left: 50%; margin-left: -15%". Previously
24
+ it would show a warning and give the view a non-functioning style:
25
+ "width: 30%; left: 50%; margin-left: 50%".
26
+ * Removes a lot of legacy default CSS attached to SC.SegmentedView. Also makes
27
+ default SproutCore theme more easily allow for sprited button images (requires
28
+ a width and height on the icon). After some consideration, the icon sizes are
29
+ set by default to: 12x12px for small, 14x14px for regular, 16x16px for large
30
+ and 24x24px for huge. These sizes fit well with the theme and although odd
31
+ numbered heights would position a bit more nicely, even numbered height icons
32
+ are much more common.
33
+ * Allows SC.State to represent the empty ("") route. Previously, there was no
34
+ way for a state to represent the empty route using representRoute:. Now a
35
+ state can set representRoute: "" to be triggered when the empty route is
36
+ fired.
37
+ * Improves SC.request.deparam so that it can accept a full URL, not just the
38
+ params section only.
39
+ * Adds SC.platform.supportsWebSQL and SC.platform.supportsIndexedDB.
40
+ * Improves the Welcome apps slightly:
41
+ - sorts the apps by name alphabetically
42
+ - groups SproutCore apps after project apps
43
+ - adds a new icon for app targets to further differentiate between the
44
+ developer's apps and the SproutCore apps (Used in the TestRunner app too)
45
+
46
+ ### DEPRECATIONS & REMOVALS
47
+
48
+ * The default value of SC.SelectView:itemSeparatorKey has been changed from
49
+ 'separator' to 'isSeparator' to match the documentation. If a property
50
+ 'separator' is found on the item, it will still be used and a developer
51
+ warning will appear in debug mode.
52
+ * The 'owner' property that is assigned to child views is deprecated and may
53
+ be removed in a future release. This property is assigned to a view's
54
+ childViews when the view is created. However, it is a duplication of the
55
+ property 'parentView' and it is not maintained properly and not assigned if a
56
+ childView is added later using appendChild() or replaceChild().
57
+
58
+
59
+ ### BUG FIXES
60
+
61
+ * Fixes minor memory leak in SC.Set. The way that SC.Set removes objects is
62
+ to "untrack" the internal index of the object by shrinking its length, but it
63
+ never actually removed the object at the last index. The only way that the
64
+ object could be freed is if a new object is inserted at the same internal
65
+ index, thus replacing it. If the objects were removed in the reverse order
66
+ that they were added, every object would still be in the set (until they were
67
+ possibly overwritten).
68
+ * Fixes moderate memory leak with bindings and observers. Previously, SC.Binding
69
+ objects and observers were never cleaned up even as views and objects were
70
+ destroyed which could prevent the views and objects from being garbage collected
71
+ and prevented the binding objects from being garbage collected.
72
+ * Fixes minor memory leak in SC.ObserverSet. Each time that a new observer is
73
+ added to an object the ObserverSet for the object will add a tracking hash for
74
+ the target and the method. As more methods are tracked for the target, they
75
+ are added and as methods are no longer tracked for the target, they are
76
+ removed. However, even when no methods are tracked for the target, an empty
77
+ tracking hash for the target still exists. This creates a small leak of memory,
78
+ because the target may have been destroyed and freed, but we are still
79
+ maintaining an empty tracking hash for it.
80
+
81
+ 1.9.1 - BUG FIX RELEASE
82
+ ----------
83
+
84
+ * Unit tests verifying ALL fixes are included.
85
+ * Fixes a bug that left childView elements in the DOM when they were rendered as
86
+ part of their parent's layer and the child was later removed.
87
+
88
+ If childView layers are rendered when the parentView's layer is created, the
89
+ `layer` property on the childView will not be cached. What occurs is that if
90
+ the childView is then removed from the parent view without ever having its
91
+ `layer` requested, when it comes time to destroy the DOM layer of the
92
+ childView, it will try to find it with a `get('layer')`. The bug was that it
93
+ only returned a layer if the view has a parent view. However, since the child
94
+ was removed from the parent first and then destroyed, it no longer has a
95
+ parent view and would not try to find its leftover DOM layer.
96
+ * Fixes improper implementation of SC.SelectionSet:constrain (fixes #870). It
97
+ was naively using forEach to iterate through the objects while mutating the
98
+ array so that the last object could never be constrained.
99
+ * Fixes implicit globals in SC.MenuPane, creating a possible memory leak.
100
+ * Fixes memory leak with child views of SC.View. The 'owner' property prevented
101
+ views from being able to be garbage collected when they are destroyed.
102
+ * Fixes SC.stringFromLayout() to include all the layout properties.
103
+ * Fixes the excess calling of parentViewDidResize on child views when the view's
104
+ position changes, but it's size doesn't. Previously, views that had fixed
105
+ sizes (i.e. width + height), but not fixed positions (i.e. not left + top)
106
+ would still call parentViewDidResize on their own child views each time that
107
+ the view's parent view resized. However, this isn't necessary, because changes
108
+ to the view's parent view will effect the view's frame, but if the view has a
109
+ fixed size, it will not effect the child view's frames.
110
+ - This fixes a strange issue that occurs with SC.ImageView's viewDidResize
111
+ implementation, where it fails to resize appropriately.
112
+ - This separates isFixedLayout into isFixedPosition + isFixedSize, allowing us
113
+ more options to decide what to do when the layout is a fixed position vs. a
114
+ fixed size vs. both vs. neither.
115
+ - Note: A similar optimization already exists in layoutDidChange.
116
+ * Fixes bug in SC.Locale that caused localizations to be overwritten by the
117
+ last language localized.
118
+ * Fixes SC.Request's application of the Content-Type header. It was incorrectly
119
+ adding the header for requests that don't have a body which would cause some
120
+ servers to reject GET or DELETE requests.
121
+ * Fixes a bug where SC.Record relationships modified within a nested store, would
122
+ fail to propagate the changes to the parent store if isMaster was NO in the
123
+ toOne or toMany attribute. This also fixes possible instances of the same bug
124
+ if using writeAttribute() and passing YES for the ignoreDidChange param inside
125
+ a nested store.
126
+
127
+ 1.9.0
128
+ ----------
129
+
130
+ ### CHANGES & FEATURES
9
131
 
10
132
  * Improves and adds much documentation.
11
133
  * Adds the Showcase app used on http://showcase.sproutcore.com. This app contains
@@ -267,7 +267,7 @@ SC.Request = SC.Object.extend(SC.Copyable, SC.Freezable,
267
267
  @returns {SC.Request|Object} receiver
268
268
  */
269
269
  header: function(key, value) {
270
- var headers;
270
+ var header, headers;
271
271
 
272
272
  if (SC.typeOf(key) === SC.T_STRING) {
273
273
  headers = this._headers;
@@ -285,9 +285,9 @@ SC.Request = SC.Object.extend(SC.Copyable, SC.Freezable,
285
285
  } else if (value === undefined) {
286
286
  headers = key;
287
287
  this.beginPropertyChanges();
288
- for(key in headers) {
289
- if (!headers.hasOwnProperty(key)) { continue; }
290
- this.header(key, headers[key]);
288
+ for(header in headers) {
289
+ if (!headers.hasOwnProperty(header)) { continue; }
290
+ this.header(header, headers[header]);
291
291
  }
292
292
  this.endPropertyChanges();
293
293
  return this;
@@ -359,15 +359,19 @@ SC.Request = SC.Object.extend(SC.Copyable, SC.Freezable,
359
359
  _prep: function() {
360
360
  var hasContentType = !!this.header('Content-Type');
361
361
 
362
- if(this.get('attachIdentifyingHeaders')) {
362
+ if (this.get('attachIdentifyingHeaders')) {
363
363
  this.header('X-Requested-With', 'XMLHttpRequest');
364
364
  this.header('X-SproutCore-Version', SC.VERSION);
365
365
  }
366
366
 
367
- if (this.get('isJSON') && !hasContentType) {
368
- this.header('Content-Type', 'application/json');
369
- } else if (this.get('isXML') && !hasContentType) {
370
- this.header('Content-Type', 'text/xml');
367
+ // Set the Content-Type header only if not specified and the request
368
+ // includes a body.
369
+ if (!hasContentType && !!this.get('body')) {
370
+ if (this.get('isJSON')) {
371
+ this.header('Content-Type', 'application/json');
372
+ } else if (this.get('isXML')) {
373
+ this.header('Content-Type', 'text/xml');
374
+ }
371
375
  }
372
376
  return this;
373
377
  },
@@ -32,6 +32,74 @@ test("Basic Requirements", function() {
32
32
  ok(contents === null, "contents is null" ) ;
33
33
  });
34
34
 
35
+ test("Default properties are correct for different types of requests.", function() {
36
+ var formBody,
37
+ headers,
38
+ jsonBody,
39
+ xmlBody,
40
+ req1, req2, req3, req4, req5;
41
+
42
+ // use this document for creating XML
43
+ xmlBody = document.implementation.createDocument(null, null, null);
44
+
45
+ // function that creates the XML structure
46
+ function o() {
47
+ var i, node = xmlBody.createElement(arguments[0]), text, child;
48
+
49
+ for(i = 1; i < arguments.length; i++) {
50
+ child = arguments[i];
51
+ if(typeof child == 'string') {
52
+ child = xmlBody.createTextNode(child);
53
+ }
54
+ node.appendChild(child);
55
+ }
56
+
57
+ return node;
58
+ }
59
+
60
+ // create the XML structure recursively
61
+ o('report',
62
+ o('submitter',
63
+ o('name', 'John Doe')
64
+ ),
65
+ o('students',
66
+ o('student',
67
+ o('name', 'Alice'),
68
+ o('grade', '80')
69
+ ),
70
+ o('student',
71
+ o('name', 'Bob'),
72
+ o('grade', '90')
73
+ )
74
+ )
75
+ );
76
+
77
+
78
+ jsonBody = { a: 1, b: 2 };
79
+ formBody = "fname=Henry&lname=Ford";
80
+ req1 = SC.Request.getUrl(url).json()._prep();
81
+ req2 = SC.Request.postUrl(url, formBody).header('Content-Type', 'application/x-www-form-urlencoded')._prep();
82
+ req3 = SC.Request.putUrl(url, xmlBody).xml()._prep();
83
+ req4 = SC.Request.patchUrl(url, jsonBody).json()._prep();
84
+ req5 = SC.Request.deleteUrl(url)._prep();
85
+
86
+ ok(req1.get('isJSON'), 'req1 should have isJSON true');
87
+ ok(!req1.get('isXML'), 'req1 should have isXML false');
88
+ equals(req1.header('Content-Type'), undefined, 'req1 should have Content-Type header as');
89
+ ok(!req2.get('isJSON'), 'req2 should have isJSON false');
90
+ ok(!req2.get('isXML'), 'req2 should have isXML false');
91
+ equals(req2.header('Content-Type'), 'application/x-www-form-urlencoded', 'req2 should have Content-Type header as');
92
+ ok(!req3.get('isJSON'), 'req3 should have isJSON false');
93
+ ok(req3.get('isXML'), 'req3 should have isXML true');
94
+ equals(req3.header('Content-Type'), 'text/xml', 'req3 should have Content-Type header as');
95
+ ok(req4.get('isJSON'), 'req4 should have isJSON true');
96
+ ok(!req4.get('isXML'), 'req4 should have isXML false');
97
+ equals(req4.header('Content-Type'), 'application/json', 'req4 should have Content-Type header as');
98
+ ok(!req5.get('isJSON'), 'req5 should have isJSON false');
99
+ ok(!req5.get('isXML'), 'req5 should have isXML false');
100
+ equals(req5.header('Content-Type'), undefined, 'req5 should have Content-Type header as');
101
+ });
102
+
35
103
  test("Test Asynchronous GET Request", function() {
36
104
 
37
105
  var response, timer;
@@ -10,41 +10,41 @@
10
10
  number formatting conventions, and localization strings. You can define
11
11
  various locales by adding them to the SC.locales hash, keyed by language
12
12
  and/or country code.
13
-
14
- On page load, the default locale will be chosen based on the current
15
- languages and saved at SC.Locale.current. This locale is used for
13
+
14
+ On page load, the default locale will be chosen based on the current
15
+ languages and saved at SC.Locale.current. This locale is used for
16
16
  localization, etc.
17
-
17
+
18
18
  ## Creating a new locale
19
-
19
+
20
20
  You can create a locale by simply extending the SC.Locale class and adding
21
21
  it to the locales hash:
22
-
22
+
23
23
  SC.Locale.locales['en'] = SC.Locale.extend({ .. config .. }) ;
24
-
24
+
25
25
  Alternatively, you could choose to base your locale on another locale by
26
26
  extending that locale:
27
-
27
+
28
28
  SC.Locale.locales['en-US'] = SC.Locale.locales['en'].extend({ ... }) ;
29
-
29
+
30
30
  Note that if you do not define your own strings property, then your locale
31
31
  will inherit any strings added to the parent locale. Otherwise you must
32
32
  implement your own strings instead.
33
-
33
+
34
34
  @extends SC.Object
35
35
  @since SproutCore 1.0
36
36
  */
37
37
  SC.Locale = SC.Object.extend({
38
-
38
+
39
39
  init: function() {
40
40
  // make sure we know the name of our own locale.
41
41
  if (!this.language) SC.Locale._assignLocales();
42
-
42
+
43
43
  // Make sure we have strings that were set using the new API. To do this
44
- // we check to a bool that is set by one of the string helpers. This
44
+ // we check to a bool that is set by one of the string helpers. This
45
45
  // indicates that the new API was used. If the new API was not used, we
46
- // check to see if the old API was used (which places strings on the
47
- // String class).
46
+ // check to see if the old API was used (which places strings on the
47
+ // String class).
48
48
  if (!this.hasStrings) {
49
49
  var langs = this._deprecatedLanguageCodes || [] ;
50
50
  langs.push(this.language);
@@ -54,18 +54,18 @@ SC.Locale = SC.Object.extend({
54
54
  strings = String[langs[idx]];
55
55
  }
56
56
  if (strings) {
57
- this.hasStrings = YES;
57
+ this.hasStrings = YES;
58
58
  this.strings = strings ;
59
59
  }
60
60
  }
61
61
  },
62
-
62
+
63
63
  /** Set to YES when strings have been added to this locale. */
64
64
  hasStrings: NO,
65
-
65
+
66
66
  /** The strings hash for this locale. */
67
67
  strings: {},
68
-
68
+
69
69
  /**
70
70
  The metrics for this locale. A metric is a singular value that is usually
71
71
  used in a user interface layout, such as "width of the OK button".
@@ -76,18 +76,18 @@ SC.Locale = SC.Object.extend({
76
76
  if (!this.language) SC.Locale._assignLocales() ;
77
77
  return "SC.Locale["+this.language+"]"+SC.guidFor(this) ;
78
78
  },
79
-
80
- /**
79
+
80
+ /**
81
81
  Returns the localized version of the string or the string if no match
82
82
  was found.
83
-
83
+
84
84
  @param {String} string
85
85
  @param {String} optional default string to return instead
86
86
  @returns {String}
87
87
  */
88
88
  locWithDefault: function(string, def) {
89
89
  var ret = this.strings[string];
90
-
90
+
91
91
  // strings may be blank, so test with typeOf.
92
92
  if (SC.typeOf(ret) === SC.T_STRING) return ret;
93
93
  else if (SC.typeOf(def) === SC.T_STRING) return def;
@@ -215,16 +215,15 @@ SC.Locale.mixin(/** @scope SC.Locale */ {
215
215
  layoutKeys: ['left', 'top', 'right', 'bottom', 'width', 'height',
216
216
  'minWidth', 'minHeight', 'centerX', 'centerY'],
217
217
 
218
- /**
219
- Invoked at the start of SproutCore's document onready handler to setup
218
+ /**
219
+ Invoked at the start of SproutCore's document onready handler to setup
220
220
  the currentLocale. This will use the language properties you have set on
221
221
  the locale to make a decision.
222
222
  */
223
223
  createCurrentLocale: function() {
224
-
225
- // get values from String if defined for compatibility with < 1.0 build
224
+ // get values from String if defined for compatibility with < 1.0 build
226
225
  // tools.
227
- var autodetect = (String.useAutodetectedLanguage !== undefined) ? String.useAutodetectedLanguage : this.useAutodetectedLanguage;
226
+ var autodetect = (String.useAutodetectedLanguage !== undefined) ? String.useAutodetectedLanguage : this.useAutodetectedLanguage;
228
227
  var preferred = (String.preferredLanguage !== undefined) ? String.preferredLanguage : this.preferredLanguage ;
229
228
 
230
229
  // determine the language
@@ -251,33 +250,33 @@ SC.Locale.mixin(/** @scope SC.Locale */ {
251
250
  localeClassFor: function(lang) {
252
251
  lang = SC.Locale.normalizeLanguage(lang) ;
253
252
  var parent, klass = this.locales[lang];
254
-
253
+
255
254
  // if locale class was not found and there is a broader-based locale
256
255
  // present, create a new locale based on that.
257
256
  if (!klass && ((parent = lang.split('-')[0]) !== lang) && (klass = this.locales[parent])) {
258
- klass = this.locales[lang] = klass.extend() ;
257
+ klass = this.locales[lang] = klass.extend() ;
259
258
  }
260
-
259
+
261
260
  // otherwise, try to create a new locale based on english.
262
261
  if (!klass) klass = this.locales[lang] = this.locales.en.extend();
263
-
262
+
264
263
  return klass;
265
264
  },
266
265
 
267
- /**
266
+ /**
268
267
  Shorthand method to define the settings for a particular locale.
269
268
  The settings you pass here will be applied directly to the locale you
270
- designate.
269
+ designate.
271
270
 
272
271
  If you are already holding a reference to a locale definition, you can
273
272
  also use this method to operate on the receiver.
274
-
275
- If the locale you name does not exist yet, this method will create the
276
- locale for you, based on the most closely related locale or english. For
273
+
274
+ If the locale you name does not exist yet, this method will create the
275
+ locale for you, based on the most closely related locale or english. For
277
276
  example, if you name the locale 'fr-CA', you will be creating a locale for
278
277
  French as it is used in Canada. This will be based on the general French
279
278
  locale (fr), since that is more generic. On the other hand, if you create
280
- a locale for mandarin (cn), it will be based on generic english (en)
279
+ a locale for mandarin (cn), it will be based on generic english (en)
281
280
  since there is no broader language code to match against.
282
281
 
283
282
  @param {String} localeName
@@ -292,20 +291,20 @@ SC.Locale.mixin(/** @scope SC.Locale */ {
292
291
  SC.mixin(locale.prototype, options) ;
293
292
  return locale ;
294
293
  },
295
-
294
+
296
295
  /**
297
- Gets the current options for the receiver locale. This is useful for
296
+ Gets the current options for the receiver locale. This is useful for
298
297
  inspecting registered locales that have not been instantiated.
299
-
298
+
300
299
  @returns {Hash} options + instance methods
301
300
  */
302
301
  options: function() { return this.prototype; },
303
-
302
+
304
303
  /**
305
304
  Adds the passed hash of strings to the locale's strings table. Note that
306
- if the receiver locale inherits its strings from its parent, then the
305
+ if the receiver locale inherits its strings from its parent, then the
307
306
  strings table will be cloned first.
308
-
307
+
309
308
  @returns {Object} receiver
310
309
  */
311
310
  addStrings: function(stringsHash) {
@@ -313,10 +312,10 @@ SC.Locale.mixin(/** @scope SC.Locale */ {
313
312
  var strings = this.prototype.strings ;
314
313
  if (strings) {
315
314
  if (!this.prototype.hasOwnProperty('strings')) {
316
- this.prototype.strings = SC.clone(strings) ;
315
+ strings = this.prototype.strings = SC.clone(strings) ;
317
316
  }
318
317
  } else strings = this.prototype.strings = {} ;
319
-
318
+
320
319
  // add strings hash
321
320
  if (stringsHash) this.prototype.strings = SC.mixin(strings, stringsHash) ;
322
321
  this.prototype.hasStrings = YES ;
@@ -336,7 +335,7 @@ SC.Locale.mixin(/** @scope SC.Locale */ {
336
335
  var metrics = this.prototype.metrics;
337
336
  if (metrics) {
338
337
  if (!this.prototype.hasOwnProperty(metrics)) {
339
- this.prototype.metrics = SC.clone(metrics) ;
338
+ metrics = this.prototype.metrics = SC.clone(metrics) ;
340
339
  }
341
340
  }
342
341
  else {
@@ -354,13 +353,13 @@ SC.Locale.mixin(/** @scope SC.Locale */ {
354
353
  },
355
354
 
356
355
  _map: { english: 'en', french: 'fr', german: 'de', japanese: 'ja', jp: 'ja', spanish: 'es' },
357
-
356
+
358
357
  /**
359
358
  Normalizes the passed language into a two-character language code.
360
359
  This method allows you to specify common languages in their full english
361
360
  name (i.e. English, French, etc). and it will be treated like their two
362
361
  letter code equivalent.
363
-
362
+
364
363
  @param {String} languageCode
365
364
  @returns {String} normalized code
366
365
  */
@@ -368,19 +367,19 @@ SC.Locale.mixin(/** @scope SC.Locale */ {
368
367
  if (!languageCode) return 'en' ;
369
368
  return SC.Locale._map[languageCode.toLowerCase()] || languageCode ;
370
369
  },
371
-
372
- // this method is called once during init to walk the installed locales
370
+
371
+ // this method is called once during init to walk the installed locales
373
372
  // and make sure they know their own names.
374
373
  _assignLocales: function() {
375
374
  for(var key in this.locales) this.locales[key].prototype.language = key;
376
375
  },
377
-
376
+
378
377
  toString: function() {
379
378
  if (!this.prototype.language) SC.Locale._assignLocales() ;
380
379
  return "SC.Locale["+this.prototype.language+"]" ;
381
380
  },
382
-
383
- // make sure important properties are copied to new class.
381
+
382
+ // make sure important properties are copied to new class.
384
383
  extend: function() {
385
384
  var ret= SC.Object.extend.apply(this, arguments) ;
386
385
  ret.addStrings= SC.Locale.addStrings;
@@ -389,14 +388,14 @@ SC.Locale.mixin(/** @scope SC.Locale */ {
389
388
  ret.toString = SC.Locale.toString ;
390
389
  return ret ;
391
390
  }
392
-
391
+
393
392
  }) ;
394
393
 
395
- /**
394
+ /**
396
395
  This locales hash contains all of the locales defined by SproutCore and
397
396
  by your own application. See the SC.Locale class definition for the
398
397
  various properties you can set on your own locales.
399
-
398
+
400
399
  @property {Hash}
401
400
  */
402
401
  SC.Locale.locales = {
@@ -413,12 +412,12 @@ SC.Locale.locales = {
413
412
  /**
414
413
  This special helper will store the strings you pass in the locale matching
415
414
  the language code. If a locale is not defined from the language code you
416
- specify, then one will be created for you with the english locale as the
415
+ specify, then one will be created for you with the english locale as the
417
416
  parent.
418
-
417
+
419
418
  @param {String} languageCode
420
419
  @param {Hash} strings
421
- @returns {Object} receiver
420
+ @returns {Object} receiver
422
421
  */
423
422
  SC.stringsFor = function(languageCode, strings) {
424
423
  // get the locale, creating one if needed.