sproutcore 1.10.2 → 1.10.3.1
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.
- checksums.yaml +8 -8
- data/CHANGELOG +11 -0
- data/VERSION.yml +1 -1
- data/lib/frameworks/sproutcore/CHANGELOG.md +34 -0
- data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/horizontal_stack_layout.js +3 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/child_view_layouts/vertical_stack_layout.js +3 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/platform.js +79 -80
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +115 -22
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +54 -17
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/statechart.js +76 -34
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/select/methods.js +18 -5
- data/lib/frameworks/sproutcore/frameworks/desktop/views/grid.js +14 -5
- data/lib/frameworks/sproutcore/frameworks/desktop/views/select.js +42 -18
- data/lib/frameworks/sproutcore/frameworks/foundation/mixins/editable.js +41 -41
- data/lib/frameworks/sproutcore/frameworks/foundation/tests/transitions/view_transitions_test.js +235 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/transitions/bounce_transition.js +8 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/transitions/fade_transition.js +6 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/transitions/pop_transition.js +8 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/transitions/scale_transition.js +6 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/transitions/slide_transition.js +6 -2
- data/lib/frameworks/sproutcore/frameworks/foundation/transitions/spring_transition.js +8 -4
- data/lib/frameworks/sproutcore/frameworks/foundation/views/inline_text_field.js +5 -4
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/system/binding.js +124 -80
- data/lib/frameworks/sproutcore/frameworks/runtime/tests/system/binding.js +134 -0
- data/lib/sproutcore.rb +1 -1
- data/lib/sproutcore/models/manifest.rb +12 -6
- data/lib/sproutcore/rack/builder.rb +20 -12
- data/lib/sproutcore/tools.rb +3 -3
- data/lib/sproutcore/tools/build.rb +22 -22
- data/sproutcore.gemspec +2 -5
- data/vendor/sproutcore/lib/yuicompressor-2.4.8.jar +0 -0
- metadata +10 -23
- data/vendor/sproutcore/lib/yuicompressor-2.4.6.jar +0 -0
@@ -105,8 +105,10 @@ SC.mixin(SC.View,
|
|
105
105
|
{ value: value, duration: duration, timing: 'ease-in-out' }
|
106
106
|
];
|
107
107
|
|
108
|
-
var callback = function () {
|
109
|
-
|
108
|
+
var callback = function (data) {
|
109
|
+
if (!data.isCancelled) {
|
110
|
+
view.didTransitionIn();
|
111
|
+
}
|
110
112
|
};
|
111
113
|
|
112
114
|
// Animate through the frames.
|
@@ -198,8 +200,10 @@ SC.mixin(SC.View,
|
|
198
200
|
{ value: finalValue, duration: duration, timing: 'ease-in' }
|
199
201
|
];
|
200
202
|
|
201
|
-
var callback = function () {
|
202
|
-
|
203
|
+
var callback = function (data) {
|
204
|
+
if (!data.isCancelled) {
|
205
|
+
view.didTransitionOut();
|
206
|
+
}
|
203
207
|
};
|
204
208
|
|
205
209
|
// Animate through the frames.
|
@@ -28,7 +28,9 @@ SC.mixin(SC.View,
|
|
28
28
|
duration: options.duration || 0.4,
|
29
29
|
timing: options.timing || 'ease'
|
30
30
|
}, function (data) {
|
31
|
-
|
31
|
+
if (!data.isCancelled) {
|
32
|
+
this.didTransitionIn();
|
33
|
+
}
|
32
34
|
});
|
33
35
|
}
|
34
36
|
},
|
@@ -48,7 +50,9 @@ SC.mixin(SC.View,
|
|
48
50
|
duration: options.duration || 0.4,
|
49
51
|
timing: options.timing || 'ease'
|
50
52
|
}, function (data) {
|
51
|
-
|
53
|
+
if (!data.isCancelled) {
|
54
|
+
this.didTransitionOut();
|
55
|
+
}
|
52
56
|
});
|
53
57
|
}
|
54
58
|
|
@@ -37,8 +37,10 @@ SC.mixin(SC.View,
|
|
37
37
|
{ value: { scale: scale }, duration: duration * 0.4, timing: 'ease-in-out' }
|
38
38
|
];
|
39
39
|
|
40
|
-
var callback = function () {
|
41
|
-
|
40
|
+
var callback = function (data) {
|
41
|
+
if (!data.isCancelled) {
|
42
|
+
view.didTransitionIn();
|
43
|
+
}
|
42
44
|
};
|
43
45
|
|
44
46
|
// Animate through the frames.
|
@@ -71,8 +73,10 @@ SC.mixin(SC.View,
|
|
71
73
|
{ value: { scale: 0 }, duration: duration * 0.6, timing: 'ease-in-out' }
|
72
74
|
];
|
73
75
|
|
74
|
-
var callback = function () {
|
75
|
-
|
76
|
+
var callback = function (data) {
|
77
|
+
if (!data.isCancelled) {
|
78
|
+
view.didTransitionOut();
|
79
|
+
}
|
76
80
|
};
|
77
81
|
|
78
82
|
// Animate through the frames.
|
@@ -27,7 +27,9 @@ SC.mixin(SC.View,
|
|
27
27
|
duration: options.duration || 0.4,
|
28
28
|
timing: options.timing || 'ease'
|
29
29
|
}, function (data) {
|
30
|
-
|
30
|
+
if (!data.isCancelled) {
|
31
|
+
this.didTransitionIn();
|
32
|
+
}
|
31
33
|
});
|
32
34
|
}
|
33
35
|
},
|
@@ -46,7 +48,9 @@ SC.mixin(SC.View,
|
|
46
48
|
duration: options.duration || 0.4,
|
47
49
|
timing: options.timing || 'ease'
|
48
50
|
}, function (data) {
|
49
|
-
|
51
|
+
if (!data.isCancelled) {
|
52
|
+
this.didTransitionOut();
|
53
|
+
}
|
50
54
|
});
|
51
55
|
}
|
52
56
|
|
@@ -71,7 +71,9 @@ SC.mixin(SC.View,
|
|
71
71
|
duration: options.duration || 0.4,
|
72
72
|
timing: options.timing || 'ease'
|
73
73
|
}, function (data) {
|
74
|
-
|
74
|
+
if (!data.isCancelled) {
|
75
|
+
this.didTransitionIn();
|
76
|
+
}
|
75
77
|
});
|
76
78
|
}
|
77
79
|
},
|
@@ -132,7 +134,9 @@ SC.mixin(SC.View,
|
|
132
134
|
duration: options.duration || 0.4,
|
133
135
|
timing: options.timing || 'ease'
|
134
136
|
}, function (data) {
|
135
|
-
|
137
|
+
if (!data.isCancelled) {
|
138
|
+
this.didTransitionOut();
|
139
|
+
}
|
136
140
|
});
|
137
141
|
}
|
138
142
|
}
|
@@ -108,8 +108,10 @@ SC.mixin(SC.View,
|
|
108
108
|
{ value: value, duration: duration, timing: 'ease-in-out' } // Hit target.
|
109
109
|
];
|
110
110
|
|
111
|
-
var callback = function () {
|
112
|
-
|
111
|
+
var callback = function (data) {
|
112
|
+
if (!data.isCancelled) {
|
113
|
+
view.didTransitionIn();
|
114
|
+
}
|
113
115
|
};
|
114
116
|
|
115
117
|
// Animate through the frames.
|
@@ -192,8 +194,10 @@ SC.mixin(SC.View,
|
|
192
194
|
{ value: finalValue, duration: duration, timing: 'ease-in' }
|
193
195
|
];
|
194
196
|
|
195
|
-
var callback = function () {
|
196
|
-
|
197
|
+
var callback = function (data) {
|
198
|
+
if (!data.isCancelled) {
|
199
|
+
view.didTransitionOut();
|
200
|
+
}
|
197
201
|
};
|
198
202
|
|
199
203
|
// Animate through the frames.
|
@@ -335,8 +335,11 @@ SC.InlineTextFieldView = SC.TextFieldView.extend(SC.InlineEditor,
|
|
335
335
|
*/
|
336
336
|
// TODO: this seems to do almost the same thing as fieldDidBlur
|
337
337
|
blurEditor: function(evt) {
|
338
|
-
if (
|
339
|
-
|
338
|
+
if (this.get('isEditing')) {
|
339
|
+
return this.commitOnBlur ? this.commitEditing() : this.discardEditing();
|
340
|
+
} else {
|
341
|
+
return true;
|
342
|
+
}
|
340
343
|
},
|
341
344
|
|
342
345
|
/**
|
@@ -436,7 +439,6 @@ SC.InlineTextFieldView = SC.TextFieldView.extend(SC.InlineEditor,
|
|
436
439
|
insertTab: function(evt) {
|
437
440
|
var target = this.target; // removed by commitEditing()
|
438
441
|
this.resignFirstResponder();
|
439
|
-
this.commitEditing() ;
|
440
442
|
if(target){
|
441
443
|
var next = target.get('nextValidKeyView');
|
442
444
|
if(next && next.beginEditing) next.beginEditing();
|
@@ -448,7 +450,6 @@ SC.InlineTextFieldView = SC.TextFieldView.extend(SC.InlineEditor,
|
|
448
450
|
insertBacktab: function(evt) {
|
449
451
|
var target = this.target; // removed by commitEditing()
|
450
452
|
this.resignFirstResponder();
|
451
|
-
this.commitEditing() ;
|
452
453
|
if(target){
|
453
454
|
var prev = target.get('previousValidKeyView');
|
454
455
|
if(prev && prev.beginEditing) prev.beginEditing();
|
@@ -1179,7 +1179,7 @@ SC.Observable = /** @scope SC.Observable.prototype */{
|
|
1179
1179
|
// observer during that round of notification. Similarly, if you're
|
1180
1180
|
// added as an observer during the notification round by another
|
1181
1181
|
// observer, you will not be notified until the next time.)
|
1182
|
-
members =
|
1182
|
+
members = observers.getMembers();
|
1183
1183
|
membersLength = members.length;
|
1184
1184
|
for (memberLoc = 0; memberLoc < membersLength; memberLoc++) {
|
1185
1185
|
member = members[memberLoc];
|
@@ -1224,7 +1224,7 @@ SC.Observable = /** @scope SC.Observable.prototype */{
|
|
1224
1224
|
if (starObservers && key !== '*') {
|
1225
1225
|
// We clone the structure per the justification, above, for regular
|
1226
1226
|
// observers.
|
1227
|
-
members =
|
1227
|
+
members = starObservers.getMembers();
|
1228
1228
|
membersLength = members.length;
|
1229
1229
|
for (memberLoc = 0; memberLoc < membersLength; memberLoc++) {
|
1230
1230
|
member = members[memberLoc];
|
@@ -267,6 +267,12 @@ SC.Binding = /** @scope SC.Binding.prototype */{
|
|
267
267
|
beget: function (fromPath) {
|
268
268
|
var ret = SC.beget(this);
|
269
269
|
ret.parentBinding = this;
|
270
|
+
// Logic gates must be recreated on beget.
|
271
|
+
if (ret._LogicGate) {
|
272
|
+
ret._logicGate = ret._LogicGate.create(ret._logicGateHash);
|
273
|
+
ret = ret.from('logicProperty', ret._logicGate).oneWay();
|
274
|
+
}
|
275
|
+
// Enables duplicate API calls for SC.Binding.beget and SC.Binding.from
|
270
276
|
if (fromPath !== undefined) ret = ret.from(fromPath);
|
271
277
|
return ret;
|
272
278
|
},
|
@@ -471,8 +477,13 @@ SC.Binding = /** @scope SC.Binding.prototype */{
|
|
471
477
|
// Mark it destroyed.
|
472
478
|
this.isDestroyed = YES;
|
473
479
|
|
474
|
-
//
|
475
|
-
if (this._logicGate)
|
480
|
+
// Clean up the logic gate, if any. (See logic gate methods.)
|
481
|
+
if (this._logicGate) {
|
482
|
+
this._logicGate.destroy();
|
483
|
+
this._logicGate = null;
|
484
|
+
this._LogicGate = null;
|
485
|
+
this._logicGateHash = null;
|
486
|
+
}
|
476
487
|
|
477
488
|
// Disconnect the binding.
|
478
489
|
this.disconnect();
|
@@ -494,6 +505,20 @@ SC.Binding = /** @scope SC.Binding.prototype */{
|
|
494
505
|
fromPropertyDidChange: function (target, key) {
|
495
506
|
var v = target ? target.get(key) : null;
|
496
507
|
|
508
|
+
// In rare circumstances, getting a property can result in observers firing,
|
509
|
+
// which may in turn run code that disconnects the binding. The cause of
|
510
|
+
// this pattern has been difficult to determine and so until a concrete test
|
511
|
+
// scenario and a lower level fix can be found, show a warning and ignore
|
512
|
+
// the update.
|
513
|
+
if (!this.isConnected) {
|
514
|
+
//@if(debug)
|
515
|
+
SC.Logger.warn("Developer Warning: A binding attempted to update after it was disconnected. The update will be ignored for binding: %@".fmt(this._fromPropertyPath, this._fromTarget, this));
|
516
|
+
//@endif
|
517
|
+
|
518
|
+
// Break early.
|
519
|
+
return;
|
520
|
+
}
|
521
|
+
|
497
522
|
// if the new value is different from the current binding value, then
|
498
523
|
// schedule to register an update.
|
499
524
|
if (v !== this._bindingValue || key === '[]') {
|
@@ -523,6 +548,20 @@ SC.Binding = /** @scope SC.Binding.prototype */{
|
|
523
548
|
|
524
549
|
var v = target.get(key);
|
525
550
|
|
551
|
+
// In rare circumstances, getting a property can result in observers firing,
|
552
|
+
// which may in turn run code that disconnects the binding. The cause of
|
553
|
+
// this pattern has been difficult to determine and so until a concrete test
|
554
|
+
// scenario and a lower level fix can be found, show a warning and ignore
|
555
|
+
// the update.
|
556
|
+
if (!this.isConnected) {
|
557
|
+
//@if(debug)
|
558
|
+
SC.Logger.warn("Developer Warning: A binding attempted to update after it was disconnected. The update will be ignored for binding: %@".fmt(this));
|
559
|
+
//@endif
|
560
|
+
|
561
|
+
// Break early.
|
562
|
+
return;
|
563
|
+
}
|
564
|
+
|
526
565
|
// if the new value is different from the current binding value, then
|
527
566
|
// schedule to register an update.
|
528
567
|
if (v !== this._transformedBindingValue) {
|
@@ -773,7 +812,7 @@ SC.Binding = /** @scope SC.Binding.prototype */{
|
|
773
812
|
if (tuple) {
|
774
813
|
this._toTarget = tuple[0];
|
775
814
|
this._toPropertyKey = tuple[1];
|
776
|
-
// Hook up _logicGate if needed (see
|
815
|
+
// Hook up _logicGate if needed (see logic gate methods).
|
777
816
|
if (this._logicGate) {
|
778
817
|
this._logicGate.set('localObject', this._toTarget);
|
779
818
|
}
|
@@ -978,112 +1017,117 @@ SC.Binding = /** @scope SC.Binding.prototype */{
|
|
978
1017
|
},
|
979
1018
|
|
980
1019
|
/**
|
981
|
-
Adds a transform
|
982
|
-
|
983
|
-
as a one-way binding, working only in the direction
|
984
|
-
|
985
|
-
'pathA' AND 'pathB' --> value (value returned is the result of ('pathA' && 'pathB'))
|
1020
|
+
Adds a transform to convert the value to the inverse of a bool value. This
|
1021
|
+
uses the same transform as bool() but inverts it.
|
986
1022
|
|
987
|
-
|
988
|
-
|
1023
|
+
@param {String} [fromPath]
|
1024
|
+
@returns {SC.Binding} this
|
1025
|
+
*/
|
1026
|
+
not: function (fromPath) {
|
1027
|
+
return this.from(fromPath).transform(function (v) {
|
1028
|
+
var t = SC.typeOf(v);
|
1029
|
+
if (t === SC.T_ERROR) return v;
|
1030
|
+
return !((t == SC.T_ARRAY) ? (v.length > 0) : (v === '') ? NO : !!v);
|
1031
|
+
});
|
1032
|
+
},
|
989
1033
|
|
990
|
-
|
991
|
-
|
992
|
-
})
|
1034
|
+
/**
|
1035
|
+
Adds a transform that will return YES if the value is null or undefined, NO otherwise.
|
993
1036
|
|
994
|
-
@param {String}
|
995
|
-
@
|
1037
|
+
@param {String} [fromPath]
|
1038
|
+
@returns {SC.Binding} this
|
996
1039
|
*/
|
997
|
-
|
1040
|
+
isNull: function (fromPath) {
|
1041
|
+
return this.from(fromPath).transform(function (v) {
|
1042
|
+
var t = SC.typeOf(v);
|
1043
|
+
return (t === SC.T_ERROR) ? v : SC.none(v);
|
1044
|
+
});
|
1045
|
+
},
|
998
1046
|
|
999
|
-
|
1047
|
+
/* @private Used with the logic gate bindings. */
|
1048
|
+
_LogicGateAnd: SC.Object.extend({
|
1049
|
+
logicProperty: function() {
|
1050
|
+
return (this.get('valueA') && this.get('valueB'));
|
1051
|
+
}.property('valueA', 'valueB').cacheable()
|
1052
|
+
}),
|
1053
|
+
/* @private Used with the logic gate bindings. */
|
1054
|
+
_LogicGateOr: SC.Object.extend({
|
1055
|
+
logicProperty: function() {
|
1056
|
+
return (this.get('valueA') || this.get('valueB'));
|
1057
|
+
}.property('valueA', 'valueB').cacheable()
|
1058
|
+
}),
|
1059
|
+
/* @private Used by logic gate bindings. */
|
1060
|
+
_logicGateBinding: function (gateClass, pathA, pathB) {
|
1061
|
+
// If either path is local, remove any * chains and append the localObject path to it.
|
1000
1062
|
if (pathA.indexOf('*') === 0 || pathA.indexOf('.') === 0) {
|
1001
|
-
pathA =
|
1063
|
+
pathA = pathA.slice(1).replace(/\*/g, '.');
|
1064
|
+
pathA = '*localObject.' + pathA;
|
1002
1065
|
}
|
1003
1066
|
if (pathB.indexOf('*') === 0 || pathB.indexOf('.') === 0) {
|
1004
|
-
pathB =
|
1067
|
+
pathB = pathB.slice(1).replace(/\*/g, '.');
|
1068
|
+
pathB = '*localObject.' + pathB;
|
1005
1069
|
}
|
1006
1070
|
|
1007
|
-
//
|
1008
|
-
var
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
1015
|
-
|
1016
|
-
|
1017
|
-
|
1018
|
-
|
1019
|
-
|
1020
|
-
|
1071
|
+
// Gets the gate class and instantiates a nice copy.
|
1072
|
+
var gateHash = {
|
1073
|
+
localObject: null,
|
1074
|
+
valueABinding: SC.Binding.oneWay(pathA),
|
1075
|
+
valueBBinding: SC.Binding.oneWay(pathB)
|
1076
|
+
},
|
1077
|
+
gate = gateClass.create(gateHash);
|
1078
|
+
|
1079
|
+
// Creates and populates the return binding.
|
1080
|
+
var ret = this.from('logicProperty', gate).oneWay();
|
1081
|
+
// This is all needed later on by beget, which must create a new logic gate instance
|
1082
|
+
// or risk bad behavior.
|
1083
|
+
ret._LogicGate = gateClass;
|
1084
|
+
ret._logicGateHash = gateHash;
|
1021
1085
|
ret._logicGate = gate;
|
1086
|
+
|
1087
|
+
// On our way.
|
1022
1088
|
return ret;
|
1023
1089
|
},
|
1024
1090
|
|
1025
1091
|
/**
|
1026
|
-
Adds a transform that forwards the '
|
1092
|
+
Adds a transform that forwards the logical 'AND' of values at 'pathA' and
|
1027
1093
|
'pathB' whenever either source changes. Note that the transform acts strictly
|
1028
1094
|
as a one-way binding, working only in the direction
|
1029
1095
|
|
1030
|
-
'pathA' AND 'pathB' --> value (value returned is the result of ('pathA'
|
1096
|
+
'pathA' AND 'pathB' --> value (value returned is the result of ('pathA' && 'pathB'))
|
1097
|
+
|
1098
|
+
Usage example where a delete button's 'isEnabled' value is determined by whether
|
1099
|
+
something is selected in a list and whether the current user is allowed to delete:
|
1100
|
+
|
1101
|
+
deleteButton: SC.ButtonView.design({
|
1102
|
+
isEnabledBinding: SC.Binding.and('MyApp.itemsController.hasSelection', 'MyApp.userController.canDelete')
|
1103
|
+
})
|
1031
1104
|
|
1032
1105
|
@param {String} pathA The first part of the conditional
|
1033
1106
|
@param {String} pathB The second part of the conditional
|
1034
1107
|
*/
|
1035
|
-
|
1036
|
-
|
1037
|
-
if (pathA.indexOf('*') === 0 || pathA.indexOf('.') === 0) {
|
1038
|
-
pathA = '*localObject.' + pathA.slice(1);
|
1039
|
-
}
|
1040
|
-
if (pathB.indexOf('*') === 0 || pathB.indexOf('.') === 0) {
|
1041
|
-
pathB = '*localObject.' + pathB.slice(1);
|
1042
|
-
}
|
1043
|
-
|
1044
|
-
// create an object to the logical computation
|
1045
|
-
var gate = SC.Object.create({
|
1046
|
-
localObject: null,
|
1047
|
-
|
1048
|
-
valueABinding: pathA,
|
1049
|
-
valueBBinding: pathB,
|
1050
|
-
|
1051
|
-
or: function () {
|
1052
|
-
return (this.get('valueA') || this.get('valueB'));
|
1053
|
-
}.property('valueA', 'valueB').cacheable()
|
1054
|
-
});
|
1055
|
-
|
1056
|
-
var ret = this.from('or', gate).oneWay();
|
1057
|
-
ret._logicGate = gate;
|
1058
|
-
return ret;
|
1108
|
+
and: function (pathA, pathB) {
|
1109
|
+
return this._logicGateBinding(this._LogicGateAnd, pathA, pathB);
|
1059
1110
|
},
|
1060
1111
|
|
1061
1112
|
/**
|
1062
|
-
Adds a transform
|
1063
|
-
|
1113
|
+
Adds a transform that forwards the 'OR' of values at 'pathA' and
|
1114
|
+
'pathB' whenever either source changes. Note that the transform acts strictly
|
1115
|
+
as a one-way binding, working only in the direction
|
1064
1116
|
|
1065
|
-
|
1066
|
-
@returns {SC.Binding} this
|
1067
|
-
*/
|
1068
|
-
not: function (fromPath) {
|
1069
|
-
return this.from(fromPath).transform(function (v) {
|
1070
|
-
var t = SC.typeOf(v);
|
1071
|
-
if (t === SC.T_ERROR) return v;
|
1072
|
-
return !((t == SC.T_ARRAY) ? (v.length > 0) : (v === '') ? NO : !!v);
|
1073
|
-
});
|
1074
|
-
},
|
1117
|
+
'pathA' OR 'pathB' --> value (value returned is the result of ('pathA' || 'pathB'))
|
1075
1118
|
|
1076
|
-
|
1077
|
-
|
1119
|
+
Usage example where a delete button's 'isEnabled' value is determined by if the
|
1120
|
+
content is editable, or if the user has admin rights:
|
1078
1121
|
|
1079
|
-
|
1080
|
-
|
1122
|
+
deleteButton: SC.ButtonView.design({
|
1123
|
+
isEnabledBinding: SC.Binding.or('*content.isEditable', 'MyApp.userController.isAdmin')
|
1124
|
+
})
|
1125
|
+
|
1126
|
+
@param {String} pathA The first part of the conditional
|
1127
|
+
@param {String} pathB The second part of the conditional
|
1081
1128
|
*/
|
1082
|
-
|
1083
|
-
return this.
|
1084
|
-
var t = SC.typeOf(v);
|
1085
|
-
return (t === SC.T_ERROR) ? v : SC.none(v);
|
1086
|
-
});
|
1129
|
+
or: function (pathA, pathB) {
|
1130
|
+
return this._logicGateBinding(this._LogicGateOr, pathA, pathB);
|
1087
1131
|
},
|
1088
1132
|
|
1089
1133
|
toString: function () {
|