sproutcore 1.11.0.rc1 → 1.11.0.rc2
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/VERSION.yml +1 -1
- data/lib/frameworks/sproutcore/CHANGELOG.md +93 -65
- data/lib/frameworks/sproutcore/apps/showcase/controllers/source_tree_controller.js +17 -7
- data/lib/frameworks/sproutcore/apps/showcase/resources/main_page.js +22 -2
- data/lib/frameworks/sproutcore/apps/showcase/resources/stylesheet.css +14 -0
- data/lib/frameworks/sproutcore/apps/showcase/resources/views_page.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/ajax/system/request.js +20 -8
- data/lib/frameworks/sproutcore/frameworks/ajax/system/websocket.js +58 -43
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/action_support.js +192 -35
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/delegate_support.js +7 -3
- data/lib/frameworks/sproutcore/frameworks/core_foundation/mixins/responder_context.js +27 -7
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/browser.js +20 -63
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/color.js +16 -7
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/event.js +279 -159
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/render_context.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/system/root_responder.js +21 -10
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/mixins/action_support.js +32 -28
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/root_responder/targetForAction.js +107 -90
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/root_responder/touch.js +33 -25
- data/lib/frameworks/sproutcore/frameworks/core_foundation/tests/system/touch.js +23 -15
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/animation.js +1 -1
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout.js +12 -6
- data/lib/frameworks/sproutcore/frameworks/core_foundation/views/view/layout_style.js +55 -33
- data/lib/frameworks/sproutcore/frameworks/datastore/system/store.js +7 -1
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/methods.js +228 -72
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/scroll/touch.js +54 -100
- data/lib/frameworks/sproutcore/frameworks/desktop/tests/views/segmented/ui.js +15 -0
- data/lib/frameworks/sproutcore/frameworks/desktop/views/button.js +57 -45
- data/lib/frameworks/sproutcore/frameworks/desktop/views/collection.js +9 -16
- data/lib/frameworks/sproutcore/frameworks/desktop/views/scroll_view.js +111 -44
- data/lib/frameworks/sproutcore/frameworks/desktop/views/segmented.js +2 -0
- data/lib/frameworks/sproutcore/frameworks/foundation/system/module.js +51 -5
- data/lib/frameworks/sproutcore/frameworks/runtime/core.js +2 -2
- data/lib/frameworks/sproutcore/frameworks/runtime/mixins/observable.js +13 -10
- data/lib/frameworks/sproutcore/frameworks/runtime/system/index_set.js +2 -1
- data/lib/frameworks/sproutcore/frameworks/runtime/system/object.js +28 -9
- data/lib/frameworks/sproutcore/frameworks/runtime/system/set.js +7 -5
- data/lib/frameworks/sproutcore/frameworks/statechart/ext/function.js +51 -46
- data/lib/frameworks/sproutcore/frameworks/statechart/system/state.js +8 -5
- data/lib/frameworks/sproutcore/frameworks/statechart/system/statechart.js +12 -3
- metadata +2 -2
@@ -10,15 +10,15 @@ sc_require('mixins/websocket_delegate');
|
|
10
10
|
@class
|
11
11
|
|
12
12
|
Implements support for WebSocket.
|
13
|
-
|
13
|
+
|
14
14
|
Example Usage:
|
15
15
|
|
16
16
|
var ws = SC.WebSocket.create({
|
17
17
|
server: 'ws://server',
|
18
18
|
}).connect();
|
19
|
-
|
19
|
+
|
20
20
|
ws.notify(this, 'wsReceivedMessage');
|
21
|
-
|
21
|
+
|
22
22
|
ws.send('message');
|
23
23
|
|
24
24
|
@since SproutCore 1.11
|
@@ -27,7 +27,7 @@ sc_require('mixins/websocket_delegate');
|
|
27
27
|
@author Nicolas BADIA
|
28
28
|
*/
|
29
29
|
SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
30
|
-
|
30
|
+
|
31
31
|
/**
|
32
32
|
URL of the WebSocket server.
|
33
33
|
|
@@ -54,9 +54,9 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
54
54
|
isConnected: false,
|
55
55
|
|
56
56
|
/**
|
57
|
-
In order to handle authentification, set `isAuth` to NO in the
|
58
|
-
`webSocketDidOpen` delegate method just after sending a request to
|
59
|
-
authentificate the connection. This way, any futher message will be put in
|
57
|
+
In order to handle authentification, set `isAuth` to NO in the
|
58
|
+
`webSocketDidOpen` delegate method just after sending a request to
|
59
|
+
authentificate the connection. This way, any futher message will be put in
|
60
60
|
queue until the server tels you the connection is authentified. Once it
|
61
61
|
did, you should set `isAuth` to YES to resume the queue.
|
62
62
|
|
@@ -64,7 +64,7 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
64
64
|
|
65
65
|
@type Boolean
|
66
66
|
@default null
|
67
|
-
*/
|
67
|
+
*/
|
68
68
|
isAuth: null,
|
69
69
|
|
70
70
|
/**
|
@@ -77,7 +77,7 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
77
77
|
|
78
78
|
/**
|
79
79
|
A WebSocket delegate.
|
80
|
-
|
80
|
+
|
81
81
|
@see SC.WebSocketDelegate
|
82
82
|
@type {SC.WebSocketDelegate}
|
83
83
|
@default null
|
@@ -109,7 +109,7 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
109
109
|
/**
|
110
110
|
Call this method to open a connection.
|
111
111
|
|
112
|
-
@returns {SC.WebSocket}
|
112
|
+
@returns {SC.WebSocket}
|
113
113
|
*/
|
114
114
|
connect: function() {
|
115
115
|
var that = this;
|
@@ -119,30 +119,30 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
119
119
|
if (!this.isSupported || this.socket) return this;
|
120
120
|
|
121
121
|
try {
|
122
|
-
var socket = this.socket = new WebSocket(this.get('server'));
|
122
|
+
var socket = this.socket = new WebSocket(this.get('server'));
|
123
123
|
|
124
124
|
socket.onopen = function() {
|
125
|
-
SC.RunLoop.begin();
|
126
|
-
that.onOpen.apply(that, arguments);
|
127
|
-
SC.RunLoop.end();
|
125
|
+
SC.RunLoop.begin();
|
126
|
+
that.onOpen.apply(that, arguments);
|
127
|
+
SC.RunLoop.end();
|
128
128
|
};
|
129
129
|
|
130
130
|
socket.onmessage = function() {
|
131
|
-
SC.RunLoop.begin();
|
132
|
-
that.onMessage.apply(that, arguments);
|
133
|
-
SC.RunLoop.end();
|
131
|
+
SC.RunLoop.begin();
|
132
|
+
that.onMessage.apply(that, arguments);
|
133
|
+
SC.RunLoop.end();
|
134
134
|
};
|
135
135
|
|
136
136
|
socket.onclose = function() {
|
137
|
-
SC.RunLoop.begin();
|
138
|
-
that.onClose.apply(that, arguments);
|
139
|
-
SC.RunLoop.end();
|
137
|
+
SC.RunLoop.begin();
|
138
|
+
that.onClose.apply(that, arguments);
|
139
|
+
SC.RunLoop.end();
|
140
140
|
};
|
141
141
|
|
142
142
|
socket.onerror = function() {
|
143
|
-
SC.RunLoop.begin();
|
144
|
-
that.onError.apply(that, arguments);
|
145
|
-
SC.RunLoop.end();
|
143
|
+
SC.RunLoop.begin();
|
144
|
+
that.onError.apply(that, arguments);
|
145
|
+
SC.RunLoop.end();
|
146
146
|
};
|
147
147
|
} catch(e) {
|
148
148
|
SC.error('An error has occurred while connnecting to the websocket server: '+e);
|
@@ -153,10 +153,10 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
153
153
|
|
154
154
|
/**
|
155
155
|
Call this method to close a connection.
|
156
|
-
|
156
|
+
|
157
157
|
@param code {Number} A numeric value indicating the status code explaining why the connection is being closed. If this parameter is not specified, a default value of 1000 (indicating a normal "transaction complete" closure) is assumed.
|
158
158
|
@param reason {String} A human-readable string explaining why the connection is closing. This string must be no longer than 123 bytes of UTF-8 text (not characters).
|
159
|
-
@returns {SC.WebSocket}
|
159
|
+
@returns {SC.WebSocket}
|
160
160
|
*/
|
161
161
|
close: function(code, reason) {
|
162
162
|
var socket = this.socket;
|
@@ -169,14 +169,14 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
169
169
|
},
|
170
170
|
|
171
171
|
/**
|
172
|
-
Configures a callback to execute when an event happen. You must pass
|
172
|
+
Configures a callback to execute when an event happen. You must pass
|
173
173
|
at least a target and action/method to this and optionally an event name.
|
174
174
|
|
175
175
|
You may also pass additional arguments which will then be passed along to
|
176
176
|
your callback.
|
177
177
|
|
178
178
|
Example:
|
179
|
-
|
179
|
+
|
180
180
|
var websocket = SC.WebSocket.create({ server: 'ws://server' }).connect();
|
181
181
|
|
182
182
|
webSocket.notify('onopen', this, 'wsWasOpen');
|
@@ -189,24 +189,35 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
189
189
|
Your notification callback should expect to receive the WebSocket object as
|
190
190
|
the first parameter and the event or message; plus any additional parameters that you pass. If your callback handles the notification and to prevent further handling, it
|
191
191
|
should return YES.
|
192
|
-
|
192
|
+
|
193
193
|
@param target {String} String Event name.
|
194
194
|
@param target {Object} The target object for the callback action.
|
195
195
|
@param action {String|Function} The method name or function to call on the target.
|
196
196
|
@returns {SC.WebSocket} The SC.WebSocket object.
|
197
197
|
*/
|
198
198
|
notify: function(event, target, action) {
|
199
|
-
var args
|
199
|
+
var args,
|
200
|
+
i, len;
|
200
201
|
|
201
202
|
if (SC.typeOf(event) !== SC.T_STRING) {
|
202
|
-
|
203
|
+
// Fast arguments access.
|
204
|
+
// Accessing `arguments.length` is just a Number and doesn't materialize the `arguments` object, which is costly.
|
205
|
+
args = new Array(arguments.length - 2); // SC.A(arguments).slice(2)
|
206
|
+
for (i = 0, len = args.length; i < len; i++) { args[i] = arguments[i + 2]; }
|
203
207
|
|
204
208
|
// Shift the arguments
|
205
209
|
action = target;
|
206
210
|
target = event;
|
207
211
|
event = 'onmessage';
|
208
212
|
} else {
|
209
|
-
|
213
|
+
if (arguments.length > 3) {
|
214
|
+
// Fast arguments access.
|
215
|
+
// Accessing `arguments.length` is just a Number and doesn't materialize the `arguments` object, which is costly.
|
216
|
+
args = new Array(arguments.length - 3); // SC.A(arguments).slice(3)
|
217
|
+
for (i = 0, len = args.length; i < len; i++) { args[i] = arguments[i + 3]; }
|
218
|
+
} else {
|
219
|
+
args = [];
|
220
|
+
}
|
210
221
|
}
|
211
222
|
|
212
223
|
var listeners = this.get('listeners');
|
@@ -214,12 +225,12 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
214
225
|
if(!listeners[event]) { listeners[event] = []; }
|
215
226
|
|
216
227
|
//@if(debug)
|
217
|
-
for (
|
228
|
+
for (i = listeners[event].length - 1; i >= 0; i--) {
|
218
229
|
var listener = listeners[event][i];
|
219
230
|
if (listener.event === event && listener.target === target && listener.action === action) {
|
220
231
|
SC.warn("Developer Warning: This listener is already defined.");
|
221
232
|
}
|
222
|
-
}
|
233
|
+
}
|
223
234
|
//@endif
|
224
235
|
|
225
236
|
// Add another listener for the given event name.
|
@@ -231,14 +242,14 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
231
242
|
/**
|
232
243
|
Send the passed message. If the connection is not yet open or anthentified,
|
233
244
|
the message will be put in the queue.
|
234
|
-
|
245
|
+
|
235
246
|
@param message {String|Object} The message to send.
|
236
|
-
@returns {SC.WebSocket}
|
247
|
+
@returns {SC.WebSocket}
|
237
248
|
*/
|
238
249
|
send: function(message) {
|
239
250
|
if (this.isConnected === true && this.isAuth !== false) {
|
240
251
|
if (this.isJSON) {
|
241
|
-
|
252
|
+
message = JSON.stringify(message);
|
242
253
|
}
|
243
254
|
|
244
255
|
this.socket.send(message);
|
@@ -272,9 +283,13 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
272
283
|
*/
|
273
284
|
onMessage: function(messageEvent) {
|
274
285
|
if (messageEvent) {
|
275
|
-
var
|
276
|
-
|
277
|
-
|
286
|
+
var del = this.get('objectDelegate'),
|
287
|
+
message,
|
288
|
+
data,
|
289
|
+
ret;
|
290
|
+
|
291
|
+
message = data = messageEvent.data;
|
292
|
+
ret = del.webSocketDidReceiveMessage(this, data);
|
278
293
|
|
279
294
|
if (ret !== true) {
|
280
295
|
if (this.isJSON) {
|
@@ -299,7 +314,7 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
299
314
|
this.socket = null;
|
300
315
|
|
301
316
|
var ret = del.webSocketDidClose(this, closeEvent);
|
302
|
-
|
317
|
+
|
303
318
|
if (ret !== true) {
|
304
319
|
this._notifyListeners('onclose', closeEvent);
|
305
320
|
this.tryReconnect();
|
@@ -310,7 +325,7 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
310
325
|
@private
|
311
326
|
*/
|
312
327
|
onError: function(event) {
|
313
|
-
var del = this.get('objectDelegate'),
|
328
|
+
var del = this.get('objectDelegate'),
|
314
329
|
ret = del.webSocketDidError(this, event);
|
315
330
|
|
316
331
|
if (ret !== true) this._notifyListeners('onerror', event);
|
@@ -404,7 +419,7 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
404
419
|
@default null
|
405
420
|
*/
|
406
421
|
socket: null,
|
407
|
-
|
422
|
+
|
408
423
|
/**
|
409
424
|
@private
|
410
425
|
|
@@ -412,7 +427,7 @@ SC.WebSocket = SC.Object.extend(SC.DelegateSupport, SC.WebSocketDelegate, {
|
|
412
427
|
@default null
|
413
428
|
*/
|
414
429
|
listeners: null,
|
415
|
-
|
430
|
+
|
416
431
|
/**
|
417
432
|
@private
|
418
433
|
|
@@ -8,73 +8,230 @@
|
|
8
8
|
/**
|
9
9
|
@class
|
10
10
|
|
11
|
-
Implements basic target
|
11
|
+
Implements basic target + action support for views. To use, simply set the `action` property on
|
12
|
+
the view to the name of a method handled by an object in the current responder chain and call
|
13
|
+
`fireAction`. If the `target` property is also set, the `action` will only be attempted on that
|
14
|
+
target object. If not set, then the responder chain will be searched for an object that implements
|
15
|
+
the named action.
|
16
|
+
|
17
|
+
*Note* Because searching the responder chain is slower, it is recommended to specify an actual
|
18
|
+
target whenever possible.
|
19
|
+
|
20
|
+
### Implementing Actions in a Target
|
21
|
+
|
22
|
+
The method signature for target + action implementors is,
|
23
|
+
|
24
|
+
methodName: function (sender, context) {
|
25
|
+
return; // Optional: return a value to the sender.
|
26
|
+
}
|
27
|
+
|
28
|
+
For views implementing `SC.ActionSupport`, the `sender` will always be `this`, which can be useful
|
29
|
+
when an action may be called by multiple views and the target needs to know from which view it was
|
30
|
+
triggered. For example, here is an action that will hide the sender's (any sender's) pane,
|
31
|
+
|
32
|
+
// Hides the pane of the current sender.
|
33
|
+
hidePane: function (sender) {
|
34
|
+
var pane = sender.get('pane');
|
35
|
+
pane.set('isVisible', false);
|
36
|
+
}
|
37
|
+
|
38
|
+
In order to pass additional information to the target, the target's action method may accept a
|
39
|
+
second argument, `context`. This argument will be the value of the same-named `context` argument
|
40
|
+
passed to `fireAction()` of the view. Here is a simple example to help illustrate this,
|
41
|
+
|
42
|
+
// Target
|
43
|
+
var theTargetObject = SC.Object.create({
|
44
|
+
|
45
|
+
theActionMethod: function (sender, context) {
|
46
|
+
console.log("theActionMethod was called at: %@".fmt(context.calledAt))
|
47
|
+
}
|
48
|
+
|
49
|
+
});
|
50
|
+
|
51
|
+
// View with SC.ActionSupport
|
52
|
+
var view = SC.View.create(SC.ActionSupport, {
|
53
|
+
action: 'theActionMethod',
|
54
|
+
target: theTargetObject,
|
55
|
+
|
56
|
+
someEvent: function () {
|
57
|
+
var addedContext = {
|
58
|
+
calledAt: new Date() // Calling specific information to pass to the target.
|
59
|
+
};
|
60
|
+
|
61
|
+
this.fireAction(addedContext);
|
62
|
+
}
|
63
|
+
|
64
|
+
});
|
12
65
|
|
13
|
-
@author Erich Ocean
|
14
|
-
@author Colin Campbell (colin@sproutcore.com)
|
15
66
|
@since SproutCore 1.7
|
16
67
|
*/
|
17
68
|
SC.ActionSupport =
|
18
69
|
/** @scope SC.ActionSupport.prototype */ {
|
19
70
|
|
71
|
+
//@if(debug)
|
72
|
+
// Provide some debug-only developer warning support.
|
73
|
+
initMixin: function () {
|
74
|
+
if (this.actionContext !== null) {
|
75
|
+
SC.warn("Developer Warning: The `actionContext` property of `SC.ActionSupport` has been deprecated. Please pass the `context` argument to `fireAction()` directly.");
|
76
|
+
}
|
77
|
+
},
|
78
|
+
//@endif
|
79
|
+
|
20
80
|
/**
|
21
|
-
The
|
81
|
+
The name of the method to call when `fireAction` is called.
|
22
82
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
the
|
83
|
+
This property is used in conjunction with the `target` property to execute a method when
|
84
|
+
`fireAction` is called. If you do not specify a target, then the responder chain will be
|
85
|
+
searched for a view that implements the named action. If you do set a target, then the button
|
86
|
+
will only try to call the method on that target.
|
27
87
|
|
28
|
-
|
29
|
-
@default null
|
30
|
-
*/
|
31
|
-
target: null,
|
88
|
+
The action method of the target should implement the following signature:
|
32
89
|
|
33
|
-
|
34
|
-
|
90
|
+
methodName: function (sender, context) {
|
91
|
+
return; // Optional: return a value to the sender.
|
92
|
+
}
|
93
|
+
|
94
|
+
### Supporting multiple actions
|
95
|
+
|
96
|
+
The most correct way to handle variable properties in SproutCore is to use a computed property.
|
97
|
+
For example, imagine if the action depended on a property, `isReady`. While we could set
|
98
|
+
`action` accordingly each time prior to calling `fireAction()` like so,
|
99
|
+
|
100
|
+
mouseUp: function () {
|
101
|
+
var isReady = this.get('isReady');
|
102
|
+
|
103
|
+
if (isReady) {
|
104
|
+
this.set('action', 'doReadyAction');
|
105
|
+
} else {
|
106
|
+
this.set('action', 'doNotReadyAction');
|
107
|
+
}
|
108
|
+
|
109
|
+
this.fireAction();
|
110
|
+
}
|
35
111
|
|
36
|
-
This
|
37
|
-
|
112
|
+
This is a bit wasteful (imagine `isReady` doesn't change very often) and leaves `action` in
|
113
|
+
an improper state (i.e. what if `isReady` changes without a call to mouseUp, then `action` is
|
114
|
+
incorrect for any code that may reference it).
|
38
115
|
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
116
|
+
The better approach is to make `action` a computed property dependent on `isReady`.
|
117
|
+
|
118
|
+
For example, the previous example would be better as,
|
119
|
+
|
120
|
+
action: function () {
|
121
|
+
return this.get('isReady') ? 'doReadyAction' : 'doNotReadyAction';
|
122
|
+
}.property('isReady'), // .cacheable() - optional to cache the result (consider memory used to cache result vs. computation time to compute result)
|
123
|
+
|
124
|
+
mouseUp: function () {
|
125
|
+
this.fireAction(); // Fires with current value of `action`.
|
126
|
+
}
|
43
127
|
|
44
128
|
@type String
|
45
129
|
@default null
|
46
130
|
*/
|
47
131
|
action: null,
|
48
132
|
|
133
|
+
/** @deprecated Version 1.11.0. Please specify `context` argument when calling fireAction method.
|
134
|
+
@type Object
|
135
|
+
@default null
|
136
|
+
*/
|
137
|
+
actionContext: null,
|
138
|
+
|
49
139
|
/**
|
50
|
-
|
51
|
-
|
140
|
+
The target to invoke the action on when `fireAction` is called.
|
141
|
+
|
142
|
+
If you set this target, the action will be called on the target object directly when the button
|
143
|
+
is clicked. If you leave this property set to `null`, then the responder chain will be
|
144
|
+
searched for a view that implements the action when the button is pressed.
|
145
|
+
|
146
|
+
The action method of the target should implement the following signature:
|
147
|
+
|
148
|
+
methodName: function (sender, context) {
|
149
|
+
return; // Optional: return a value to the sender.
|
150
|
+
}
|
151
|
+
|
152
|
+
### Supporting multiple targets
|
153
|
+
|
154
|
+
The most correct way to handle variable properties in SproutCore is to use a computed property.
|
155
|
+
For example, imagine if the target depended on a property, `isReady`. While we could set
|
156
|
+
`target` accordingly each time prior to calling `fireAction()` like so,
|
157
|
+
|
158
|
+
mouseUp: function () {
|
159
|
+
var isReady = this.get('isReady');
|
160
|
+
|
161
|
+
if (isReady) {
|
162
|
+
this.set('target', MyApp.readyTarget);
|
163
|
+
} else {
|
164
|
+
this.set('target', MyApp.notReadyTarget);
|
165
|
+
}
|
166
|
+
|
167
|
+
this.fireAction();
|
168
|
+
}
|
169
|
+
|
170
|
+
This is a bit wasteful (imagine `isReady` doesn't change very often) and leaves `target` in
|
171
|
+
an improper state (i.e. what if `isReady` changes without a call to mouseUp, then `target` is
|
172
|
+
incorrect for any code that may reference it).
|
173
|
+
|
174
|
+
The better approach is to make `target` a computed property dependent on `isReady`.
|
175
|
+
|
176
|
+
For example, the previous example would be better as,
|
177
|
+
|
178
|
+
target: function () {
|
179
|
+
return this.get('isReady') ? MyApp.readyTarget : MyApp.notReadyTarget;
|
180
|
+
}.property('isReady'), // .cacheable() - optional to cache the result (consider memory used to cache result vs. computation time to compute result)
|
181
|
+
|
182
|
+
mouseUp: function () {
|
183
|
+
this.fireAction(); // Fires with current value of `target`.
|
184
|
+
}
|
52
185
|
|
53
186
|
@type Object
|
54
187
|
@default null
|
55
188
|
*/
|
56
|
-
|
189
|
+
target: null,
|
57
190
|
|
58
191
|
/**
|
59
|
-
Perform the action. If
|
60
|
-
the
|
192
|
+
Perform the current action on the current target with the given context. If no target is set,
|
193
|
+
then the responder chain will be searched for an object that implements the action.
|
61
194
|
|
62
|
-
|
195
|
+
You can pass the `context` parameter, which is useful in order to provide additional
|
196
|
+
information to the target, such as the current state of the sender when the action was
|
197
|
+
triggered.
|
63
198
|
|
64
|
-
@
|
65
|
-
@returns {Boolean} false otherwise
|
199
|
+
@param {Object} [context] additional context information to pass to the target
|
200
|
+
@returns {Boolean} true if successful; false otherwise
|
66
201
|
*/
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
202
|
+
// TODO: remove backwards compatibility for `action` argument
|
203
|
+
fireAction: function (actionOrContext) {
|
204
|
+
var pane = this.get('pane'),
|
205
|
+
rootResponder = pane.get('rootResponder'),
|
206
|
+
action = this.get('action'),
|
207
|
+
context;
|
208
|
+
|
209
|
+
// Normalize arguments.
|
210
|
+
// TODO: Fully deprecate action argument and actionContext property.
|
211
|
+
|
212
|
+
// No argument, use action (above) and actionContext properties.
|
213
|
+
if (actionOrContext === undefined) {
|
214
|
+
context = this.get('actionContext');
|
215
|
+
|
216
|
+
// String argument and no action (above) property, assume action method name. Use argument with actionContext property.
|
217
|
+
} else if (typeof actionOrContext === SC.T_STRING && action == null) {
|
218
|
+
//@if(debug)
|
219
|
+
// Provide some debug-only developer warning support.
|
220
|
+
SC.warn("Developer Warning: The signature of `SC.ActionSupport.prototype.fireAction` has changed. Please set the `action` property on your view and only pass an optional context argument to `fireAction`.");
|
221
|
+
//@endif
|
222
|
+
action = actionOrContext;
|
223
|
+
context = this.get('actionContext');
|
224
|
+
|
225
|
+
// Something else, use action property (above) and context argument.
|
226
|
+
} else {
|
227
|
+
context = actionOrContext;
|
228
|
+
}
|
72
229
|
|
73
230
|
if (action && rootResponder) {
|
74
|
-
return rootResponder.sendAction(action,
|
231
|
+
return rootResponder.sendAction(action, this.get('target'), this, pane, context, this);
|
75
232
|
}
|
76
233
|
|
77
234
|
return false;
|
78
235
|
}
|
79
236
|
|
80
|
-
};
|
237
|
+
};
|