sproutcore 1.0.1008 → 1.0.1009

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION.yml CHANGED
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  :major: 1
3
3
  :minor: 0
4
- :patch: 1008
5
- :digest: 1f1bdc7c02d51c49bd6d5e2b07a0dd2b0a75150c
4
+ :patch: 1009
5
+ :digest: 88cb568a49aec110427db79f1e1249ca840b2a66
@@ -25,7 +25,7 @@ Brian Cully
25
25
  Charles Jolley
26
26
  Chris Hyle
27
27
  Colin Campbell
28
- Cortlan Klien
28
+ Cortlan Klein
29
29
  Erich Ocean
30
30
  Evin Grano
31
31
  Geoffrey Donaldson
@@ -446,7 +446,7 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
446
446
  changed.forEach(function(storeKey) {
447
447
  // get record - do not include EMPTY or DESTROYED records
448
448
  status = store.peekStatus(storeKey);
449
- if (!(status & K.EMPTY) && !(status & K.DESTROYED)) {
449
+ if (!(status & K.EMPTY) && !((status & K.DESTROYED) || (status === K.BUSY_DESTROYING))) {
450
450
  rec = store.materializeRecord(storeKey);
451
451
  included = !!(rec && query.contains(rec));
452
452
  } else included = NO ;
@@ -490,7 +490,7 @@ SC.RecordArray = SC.Object.extend(SC.Enumerable, SC.Array,
490
490
  storeKeys = [];
491
491
  sourceKeys.forEach(function(storeKey) {
492
492
  status = store.peekStatus(storeKey);
493
- if (!(status & K.EMPTY) && !(status & K.DESTROYED)) {
493
+ if (!(status & K.EMPTY) && !((status & K.DESTROYED) || (status === K.BUSY_DESTROYING))) {
494
494
  rec = store.materializeRecord(storeKey);
495
495
  if (rec && query.contains(rec)) storeKeys.push(storeKey);
496
496
  }
@@ -61,6 +61,24 @@ SC.ListView = SC.CollectionView.extend(
61
61
  classNames: ['sc-list-view'],
62
62
 
63
63
  acceptsFirstResponder: YES,
64
+
65
+ /**
66
+ * If set to YES, the default theme will show alternating rows
67
+ * for the views this ListView created through exampleView property.
68
+ *
69
+ * @property {Boolean}
70
+ */
71
+ showAlternatingRows: NO,
72
+
73
+ // ..........................................................
74
+ // METHODS
75
+ //
76
+
77
+ render: function(context, firstTime) {
78
+ context.setClass('alternating', this.get('showAlternatingRows'));
79
+
80
+ return sc_super();
81
+ },
64
82
 
65
83
  // ..........................................................
66
84
  // COLLECTION ROW DELEGATE SUPPORT
@@ -127,6 +127,7 @@ SC.ListItemView = SC.View.extend(
127
127
  */
128
128
  contentIsBranchKey: null,
129
129
 
130
+
130
131
  /**
131
132
  YES if the item view is currently editing.
132
133
  */
@@ -152,9 +153,22 @@ SC.ListItemView = SC.View.extend(
152
153
 
153
154
  contentPropertyDidChange: function() {
154
155
  //if (this.get('isEditing')) this.discardEditing() ;
156
+ if (this.get('contentIsEditable') !== this.contentIsEditable()) {
157
+ this.notifyPropertyChange('contentIsEditable');
158
+ }
159
+
155
160
  this.displayDidChange();
156
161
  },
157
162
 
163
+ /**
164
+ Determines if content is editable or not. Checkboxes and other related
165
+ components will render disabled if an item is not editable.
166
+ */
167
+ contentIsEditable: function() {
168
+ var content = this.get('content');
169
+ return content && (content.get('isEditable')!==NO);
170
+ }.property('content').cacheable(),
171
+
158
172
  /**
159
173
  Fills the passed html-array with strings that can be joined to form the
160
174
  innerHTML of the receiver element. Also populates an array of classNames
@@ -171,6 +185,10 @@ SC.ListItemView = SC.View.extend(
171
185
  indent = this.get('outlineIndent'),
172
186
  key, value, working ;
173
187
 
188
+ // add alternating row classes
189
+ context.addClass((this.get('contentIndex')%2 === 0) ? 'even' : 'odd');
190
+ context.setClass('disabled', !this.get('isEnabled'));
191
+
174
192
  // outline level wrapper
175
193
  working = context.begin("div").addClass("sc-outline");
176
194
  if (level>=0 && indent>0) working.addStyle("left", indent*(level+1));
@@ -282,8 +300,10 @@ SC.ListItemView = SC.View.extend(
282
300
 
283
301
  var key = (state === SC.MIXED_STATE) ? "mixed" : state ? "sel" : "nosel",
284
302
  cache = this._scli_checkboxHtml,
303
+ isEnabled = this.get('contentIsEditable') && this.get('isEnabled'),
285
304
  html, tmp;
286
305
 
306
+ if (!isEnabled) key = SC.keyFor('disabled', key);
287
307
  if (!cache) cache = this.constructor.prototype._scli_checkboxHtml = {};
288
308
  html = cache[key];
289
309
 
@@ -294,6 +314,9 @@ SC.ListItemView = SC.View.extend(
294
314
  // set state on html
295
315
  if (state === SC.MIXED_STATE) tmp.addClass('mixed');
296
316
  else tmp.setClass('sel', state);
317
+
318
+ // disabled
319
+ tmp.setClass('disabled', !isEnabled);
297
320
 
298
321
  // now add inner content. note we do not add a real checkbox because
299
322
  // we don't want to have to setup a change observer on it.
@@ -463,6 +486,11 @@ SC.ListItemView = SC.View.extend(
463
486
  button.
464
487
  */
465
488
  mouseDown: function(evt) {
489
+
490
+ // if content is not editable, then always let collection view handle the
491
+ // event.
492
+ if (!this.get('contentIsEditable')) return NO ;
493
+
466
494
  // if occurred inside checkbox, item view should handle the event.
467
495
  if (this._isInsideCheckbox(evt)) {
468
496
  this._addCheckboxActiveState() ;
@@ -608,6 +636,7 @@ SC.ListItemView = SC.View.extend(
608
636
 
609
637
  beginEditing: function() {
610
638
  if (this.get('isEditing')) return YES ;
639
+ //if (!this.get('contentIsEditable')) return NO ;
611
640
  return this._beginEditing(YES);
612
641
  },
613
642
 
@@ -512,10 +512,14 @@ SC.SplitView = SC.View.extend(
512
512
  mouseUp: function(evt) {
513
513
  // console.log('%@.mouseUp(%@, %@)'.fmt(this, evt));
514
514
  // console.log(evt.originalEvent);
515
- this._thumbView = null ; // avoid memory leaks
516
- this._inLiveResize = NO ;
517
- this.endLiveResize() ;
518
- return YES ;
515
+ if (this._inLiveResize === YES) {
516
+ this._thumbView = null ; // avoid memory leaks
517
+ this._inLiveResize = NO ;
518
+ this.endLiveResize() ;
519
+ return YES ;
520
+ }
521
+
522
+ return NO ;
519
523
  },
520
524
 
521
525
  doubleClickInThumbView: function(evt, thumbView) {
@@ -33,7 +33,7 @@ SC.json = {
33
33
 
34
34
  /*
35
35
  http://www.JSON.org/json2.js
36
- 2008-11-19
36
+ 2009-09-29
37
37
 
38
38
  Public Domain.
39
39
 
@@ -66,7 +66,7 @@ SC.json = {
66
66
  value represented by the name/value pair that should be serialized,
67
67
  or undefined if nothing should be serialized. The toJSON method
68
68
  will be passed the key associated with the value, and this will be
69
- bound to the object holding the key.
69
+ bound to the value
70
70
 
71
71
  For example, this would serialize Dates as ISO strings.
72
72
 
@@ -177,9 +177,7 @@ SC.json = {
177
177
  NOT CONTROL.
178
178
  */
179
179
 
180
- /*jslint evil: true */
181
-
182
- /*global JSON */
180
+ /*jslint evil: true, strict: false */
183
181
 
184
182
  /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply,
185
183
  call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours,
@@ -188,12 +186,14 @@ SC.json = {
188
186
  test, toJSON, toString, valueOf
189
187
  */
190
188
 
189
+
191
190
  // Create a JSON object only if one does not already exist. We create the
192
191
  // methods in a closure to avoid creating global variables.
193
192
 
194
193
  if (!this.JSON) {
195
- JSON = {};
194
+ this.JSON = {};
196
195
  }
196
+
197
197
  (function () {
198
198
 
199
199
  function f(n) {
@@ -205,12 +205,13 @@ if (!this.JSON) {
205
205
 
206
206
  Date.prototype.toJSON = function (key) {
207
207
 
208
- return this.getUTCFullYear() + '-' +
208
+ return isFinite(this.valueOf()) ?
209
+ this.getUTCFullYear() + '-' +
209
210
  f(this.getUTCMonth() + 1) + '-' +
210
211
  f(this.getUTCDate()) + 'T' +
211
212
  f(this.getUTCHours()) + ':' +
212
213
  f(this.getUTCMinutes()) + ':' +
213
- f(this.getUTCSeconds()) + 'Z';
214
+ f(this.getUTCSeconds()) + 'Z' : null;
214
215
  };
215
216
 
216
217
  String.prototype.toJSON =
@@ -267,14 +268,9 @@ if (!this.JSON) {
267
268
  value = holder[key];
268
269
 
269
270
  // If the value has a toJSON method, call it to obtain a replacement value.
270
-
271
- /* FIXME: Prototype.js is creating an object.toJSON function which is not
272
- is not playing well with json2.js. Arrays are not being JSON.stringify
273
- correctly. Someone may want to check that this is correct.
274
- */
271
+
275
272
  if (value && typeof value === 'object' &&
276
- typeof value.toJSON === 'function' &&
277
- Object.prototype.toString.apply(value) !== '[object Array]') {
273
+ typeof value.toJSON === 'function') {
278
274
  value = value.toJSON(key);
279
275
  }
280
276
 
@@ -344,7 +340,7 @@ if (!this.JSON) {
344
340
  mind + ']' :
345
341
  '[' + partial.join(',') + ']';
346
342
  gap = mind;
347
- return v;
343
+ return v;
348
344
  }
349
345
 
350
346
  // If the replacer is an array, use it to select the members to be stringified.
@@ -435,6 +431,82 @@ if (!this.JSON) {
435
431
  // If the JSON object does not yet have a parse method, give it one.
436
432
 
437
433
  if (typeof JSON.parse !== 'function') {
438
- JSON.parse = function(text) { return eval('('+text+')'); };
434
+ JSON.parse = function (text, reviver) {
435
+
436
+ // The parse method takes a text and an optional reviver function, and returns
437
+ // a JavaScript value if the text is a valid JSON text.
438
+
439
+ var j;
440
+
441
+ function walk(holder, key) {
442
+
443
+ // The walk method is used to recursively walk the resulting structure so
444
+ // that modifications can be made.
445
+
446
+ var k, v, value = holder[key];
447
+ if (value && typeof value === 'object') {
448
+ for (k in value) {
449
+ if (Object.hasOwnProperty.call(value, k)) {
450
+ v = walk(value, k);
451
+ if (v !== undefined) {
452
+ value[k] = v;
453
+ } else {
454
+ delete value[k];
455
+ }
456
+ }
457
+ }
458
+ }
459
+ return reviver.call(holder, key, value);
460
+ }
461
+
462
+
463
+ // Parsing happens in four stages. In the first stage, we replace certain
464
+ // Unicode characters with escape sequences. JavaScript handles many characters
465
+ // incorrectly, either silently deleting them, or treating them as line endings.
466
+
467
+ cx.lastIndex = 0;
468
+ if (cx.test(text)) {
469
+ text = text.replace(cx, function (a) {
470
+ return '\\u' +
471
+ ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
472
+ });
473
+ }
474
+
475
+ // In the second stage, we run the text against regular expressions that look
476
+ // for non-JSON patterns. We are especially concerned with '()' and 'new'
477
+ // because they can cause invocation, and '=' because it can cause mutation.
478
+ // But just to be safe, we want to reject all unexpected forms.
479
+
480
+ // We split the second stage into 4 regexp operations in order to work around
481
+ // crippling inefficiencies in IE's and Safari's regexp engines. First we
482
+ // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we
483
+ // replace all simple value tokens with ']' characters. Third, we delete all
484
+ // open brackets that follow a colon or comma or that begin the text. Finally,
485
+ // we look to see that the remaining characters are only whitespace or ']' or
486
+ // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval.
487
+
488
+ if (/^[\],:{}\s]*$/.
489
+ test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@').
490
+ replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']').
491
+ replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) {
492
+
493
+ // In the third stage we use the eval function to compile the text into a
494
+ // JavaScript structure. The '{' operator is subject to a syntactic ambiguity
495
+ // in JavaScript: it can begin a block or an object literal. We wrap the text
496
+ // in parens to eliminate the ambiguity.
497
+
498
+ j = eval('(' + text + ')');
499
+
500
+ // In the optional fourth stage, we recursively walk the new structure, passing
501
+ // each name/value pair to a reviver function for possible transformation.
502
+
503
+ return typeof reviver === 'function' ?
504
+ walk({'': j}, '') : j;
505
+ }
506
+
507
+ // If the text is not JSON parseable, then a SyntaxError is thrown.
508
+
509
+ throw new SyntaxError('JSON.parse');
510
+ };
439
511
  }
440
- })();
512
+ }());
@@ -10,11 +10,19 @@
10
10
  color: #000;
11
11
  }
12
12
 
13
+ .sc-theme .sc-collection-view.alternating .sc-collection-item.even {
14
+ background-color: #e4e4e4;
15
+ }
16
+
13
17
  .sc-theme .sc-collection-view .sc-collection-item.sel {
14
18
  background-color: #ddd;
15
19
  color: #333;
16
20
  }
17
21
 
22
+ .sc-theme.focus .sc-collection-view.alternating .sc-collection-item.even {
23
+ background-color: #f4f7fb;
24
+ }
25
+
18
26
  .sc-theme.focus .sc-collection-view.focus .sc-collection-item.sel {
19
27
  background-color: #2370d8;
20
28
  color: white ;
@@ -10,7 +10,7 @@
10
10
 
11
11
  @extends <%= base_class_name || 'SC.DataSource' %>
12
12
  */
13
- <%= namespace_class_name %> = <%= base_class_name || 'SC.DataSource' %>.create(
13
+ <%= namespace_class_name %> = <%= base_class_name || 'SC.DataSource' %>.extend(
14
14
  /** @scope <%= namespace_class_name %>.prototype */ {
15
15
 
16
16
  // ..........................................................
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sproutcore}
8
- s.version = "1.0.1008"
8
+ s.version = "1.0.1009"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Sprout Systems, Inc. Apple Inc. and contributors"]
12
- s.date = %q{2009-10-23}
12
+ s.date = %q{2009-10-26}
13
13
  s.description = %q{sproutcore - abbot
14
14
  by Charles Jolley and contributors
15
15
  http://www.sproutcore.com
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sproutcore
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1008
4
+ version: 1.0.1009
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sprout Systems, Inc. Apple Inc. and contributors
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-23 00:00:00 -07:00
12
+ date: 2009-10-26 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency