sproutcore 1.0.1008 → 1.0.1009
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/VERSION.yml +2 -2
- data/frameworks/sproutcore/README +1 -1
- data/frameworks/sproutcore/frameworks/datastore/system/record_array.js +2 -2
- data/frameworks/sproutcore/frameworks/desktop/views/list.js +18 -0
- data/frameworks/sproutcore/frameworks/desktop/views/list_item.js +29 -0
- data/frameworks/sproutcore/frameworks/desktop/views/split.js +8 -4
- data/frameworks/sproutcore/frameworks/foundation/system/json.js +90 -18
- data/frameworks/sproutcore/themes/standard_theme/english.lproj/collection.css +8 -0
- data/gen/data-source/templates/data_sources/@filename@.js +1 -1
- data/sproutcore-abbot.gemspec +2 -2
- metadata +2 -2
data/VERSION.yml
CHANGED
@@ -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
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
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
|
-
|
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
|
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.
|
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
|
-
|
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
|
-
|
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' %>.
|
13
|
+
<%= namespace_class_name %> = <%= base_class_name || 'SC.DataSource' %>.extend(
|
14
14
|
/** @scope <%= namespace_class_name %>.prototype */ {
|
15
15
|
|
16
16
|
// ..........................................................
|
data/sproutcore-abbot.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{sproutcore}
|
8
|
-
s.version = "1.0.
|
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-
|
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.
|
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-
|
12
|
+
date: 2009-10-26 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|