canjs-rails 0.1.0 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,42 +1,48 @@
1
- (function(can, window, undefined){
2
-
3
-
4
-
1
+ /*
2
+ * CanJS - 1.1.2 (2012-11-28)
3
+ * http://canjs.us/
4
+ * Copyright (c) 2012 Bitovi
5
+ * Licensed MIT
6
+ */
7
+ (function (can, window, undefined) {
8
+ // ## can/observe/delegate/delegate.js
9
+
10
+
11
+
5
12
  // ** - 'this' will be the deepest item changed
6
13
  // * - 'this' will be any changes within *, but * will be the
7
14
  // this returned
8
-
9
15
  // tells if the parts part of a delegate matches the broken up props of the event
10
16
  // gives the prop to use as 'this'
11
17
  // - parts - the attribute name of the delegate split in parts ['foo','*']
12
18
  // - props - the split props of the event that happened ['foo','bar','0']
13
19
  // - returns - the attribute to delegate too ('foo.bar'), or null if not a match
14
- var matches = function(parts, props){
20
+ var matches = function (parts, props) {
15
21
  //check props parts are the same or
16
22
  var len = parts.length,
17
- i =0,
23
+ i = 0,
18
24
  // keeps the matched props we will use
19
25
  matchedProps = [],
20
26
  prop;
21
-
27
+
22
28
  // if the event matches
23
- for(i; i< len; i++){
24
- prop = props[i]
29
+ for (i; i < len; i++) {
30
+ prop = props[i]
25
31
  // if no more props (but we should be matching them)
26
32
  // return null
27
- if( typeof prop !== 'string' ) {
33
+ if (typeof prop !== 'string') {
28
34
  return null;
29
35
  } else
30
36
  // if we have a "**", match everything
31
- if( parts[i] == "**" ) {
37
+ if (parts[i] == "**") {
32
38
  return props.join(".");
33
- } else
39
+ } else
34
40
  // a match, but we want to delegate to "*"
35
- if (parts[i] == "*"){
41
+ if (parts[i] == "*") {
36
42
  // only do this if there is nothing after ...
37
43
  matchedProps.push(prop);
38
44
  }
39
- else if( prop === parts[i] ) {
45
+ else if (prop === parts[i]) {
40
46
  matchedProps.push(prop);
41
47
  } else {
42
48
  return null;
@@ -46,299 +52,139 @@
46
52
  },
47
53
  // gets a change event and tries to figure out which
48
54
  // delegates to call
49
- delegate = function(event, prop, how, newVal, oldVal){
55
+ delegate = function (event, prop, how, newVal, oldVal) {
50
56
  // pre-split properties to save some regexp time
51
57
  var props = prop.split("."),
52
58
  delegates = (this._observe_delegates || []).slice(0),
53
- delegate,
54
- attr,
55
- matchedAttr,
56
- hasMatch,
57
- valuesEqual;
59
+ delegate, attr, matchedAttr, hasMatch, valuesEqual;
58
60
  event.attr = prop;
59
- event.lastAttr = props[props.length -1 ];
60
-
61
+ event.lastAttr = props[props.length - 1];
62
+
61
63
  // for each delegate
62
- for(var i =0; delegate = delegates[i++];){
63
-
64
+ for (var i = 0; delegate = delegates[i++];) {
65
+
64
66
  // if there is a batchNum, this means that this
65
67
  // event is part of a series of events caused by a single
66
68
  // attrs call. We don't want to issue the same event
67
69
  // multiple times
68
70
  // setting the batchNum happens later
69
- if((event.batchNum && delegate.batchNum === event.batchNum) || delegate.undelegated ){
71
+ if ((event.batchNum && delegate.batchNum === event.batchNum) || delegate.undelegated) {
70
72
  continue;
71
73
  }
72
-
74
+
73
75
  // reset match and values tests
74
76
  hasMatch = undefined;
75
77
  valuesEqual = true;
76
-
78
+
79
+ // yeah, all this under here has to be redone v
77
80
  // for each attr in a delegate
78
- for(var a =0 ; a < delegate.attrs.length; a++){
79
-
81
+ for (var a = 0; a < delegate.attrs.length; a++) {
82
+
80
83
  attr = delegate.attrs[a];
81
-
84
+
82
85
  // check if it is a match
83
- if(matchedAttr = matches(attr.parts, props)){
86
+ if (matchedAttr = matches(attr.parts, props)) {
84
87
  hasMatch = matchedAttr;
85
88
  }
86
89
  // if it has a value, make sure it's the right value
87
90
  // if it's set, we should probably check that it has a
88
91
  // value no matter what
89
- if(attr.value && valuesEqual /* || delegate.hasValues */){
90
- valuesEqual = attr.value === ""+this.attr(attr.attr)
91
- } else if (valuesEqual && delegate.attrs.length > 1){
92
+ if (attr.value && valuesEqual) {
93
+ valuesEqual = attr.value === "" + this.attr(attr.attr)
94
+ } else if (valuesEqual && delegate.attrs.length > 1) {
92
95
  // if there are multiple attributes, each has to at
93
96
  // least have some value
94
97
  valuesEqual = this.attr(attr.attr) !== undefined
95
98
  }
96
99
  }
97
-
98
- // if there is a match and valuesEqual ... call back
99
100
 
100
- if(hasMatch && valuesEqual) {
101
+
102
+ // if there is a match and valuesEqual ... call back
103
+ if (hasMatch && valuesEqual) {
101
104
  // how to get to the changed property from the delegate
102
- var from = prop.replace(hasMatch+".","");
103
-
105
+ var from = prop.replace(hasMatch + ".", "");
106
+
104
107
  // if this event is part of a batch, set it on the delegate
105
108
  // to only send one event
106
- if(event.batchNum ){
109
+ if (event.batchNum) {
107
110
  delegate.batchNum = event.batchNum
108
111
  }
109
-
112
+
110
113
  // if we listen to change, fire those with the same attrs
111
114
  // TODO: the attrs should probably be using from
112
- if( delegate.event === 'change' ){
115
+ if (delegate.event === 'change') {
113
116
  arguments[1] = from;
114
117
  event.curAttr = hasMatch;
115
- delegate.callback.apply(this.attr(hasMatch), can.makeArray( arguments));
116
- } else if(delegate.event === how ){
117
-
118
+ delegate.callback.apply(this.attr(hasMatch), can.makeArray(arguments));
119
+ } else if (delegate.event === how) {
120
+
118
121
  // if it's a match, callback with the location of the match
119
- delegate.callback.apply(this.attr(hasMatch), [event,newVal, oldVal, from]);
120
- } else if(delegate.event === 'set' &&
121
- how == 'add' ) {
122
+ delegate.callback.apply(this.attr(hasMatch), [event, newVal, oldVal, from]);
123
+ } else if (delegate.event === 'set' && how == 'add') {
122
124
  // if we are listening to set, we should also listen to add
123
- delegate.callback.apply(this.attr(hasMatch), [event,newVal, oldVal, from]);
125
+ delegate.callback.apply(this.attr(hasMatch), [event, newVal, oldVal, from]);
124
126
  }
125
127
  }
126
-
128
+
127
129
  }
128
130
  };
129
-
130
- can.extend(can.Observe.prototype,{
131
- /**
132
- * @function can.Observe.prototype.delegate
133
- * @parent can.Observe.delegate
134
- * @plugin can/observe/delegate
135
- *
136
- * `delegate( selector, event, handler(ev,newVal,oldVal,from) )` listen for changes
137
- * in a child attribute from the parent. The child attribute
138
- * does not have to exist.
139
- *
140
- *
141
- * // create an observable
142
- * var observe = can.Observe({
143
- * foo : {
144
- * bar : "Hello World"
145
- * }
146
- * })
147
- *
148
- * //listen to changes on a property
149
- * observe.delegate("foo.bar","change", function(ev, prop, how, newVal, oldVal){
150
- * // foo.bar has been added, set, or removed
151
- * this //->
152
- * });
153
- *
154
- * // change the property
155
- * observe.attr('foo.bar',"Goodbye Cruel World")
156
- *
157
- * ## Types of events
158
- *
159
- * Delegate lets you listen to add, set, remove, and change events on property.
160
- *
161
- * __add__
162
- *
163
- * An add event is fired when a new property has been added.
164
- *
165
- * var o = new can.Control({});
166
- * o.delegate("name","add", function(ev, value){
167
- * // called once
168
- * can.$('#name').show()
169
- * })
170
- * o.attr('name',"Justin")
171
- * o.attr('name',"Brian");
172
- *
173
- * Listening to add events is useful for 'setup' functionality (in this case
174
- * showing the <code>#name</code> element.
175
- *
176
- * __set__
177
- *
178
- * Set events are fired when a property takes on a new value. set events are
179
- * always fired after an add.
180
- *
181
- * o.delegate("name","set", function(ev, value){
182
- * // called twice
183
- * can.$('#name').text(value)
184
- * })
185
- * o.attr('name',"Justin")
186
- * o.attr('name',"Brian");
187
- *
188
- * __remove__
189
- *
190
- * Remove events are fired after a property is removed.
191
- *
192
- * o.delegate("name","remove", function(ev){
193
- * // called once
194
- * $('#name').text(value)
195
- * })
196
- * o.attr('name',"Justin");
197
- * o.removeAttr('name');
198
- *
199
- * ## Wildcards - matching multiple properties
200
- *
201
- * Sometimes, you want to know when any property within some part
202
- * of an observe has changed. Delegate lets you use wildcards to
203
- * match any property name. The following listens for any change
204
- * on an attribute of the params attribute:
205
- *
206
- * var o = can.Control({
207
- * options : {
208
- * limit : 100,
209
- * offset: 0,
210
- * params : {
211
- * parentId: 5
212
- * }
213
- * }
214
- * })
215
- * o.delegate('options.*','change', function(){
216
- * alert('1');
217
- * })
218
- * o.delegate('options.**','change', function(){
219
- * alert('2');
220
- * })
221
- *
222
- * // alerts 1
223
- * // alerts 2
224
- * o.attr('options.offset',100)
225
- *
226
- * // alerts 2
227
- * o.attr('options.params.parentId',6);
228
- *
229
- * Using a single wildcard (<code>*</code>) matches single level
230
- * properties. Using a double wildcard (<code>**</code>) matches
231
- * any deep property.
232
- *
233
- * ## Listening on multiple properties and values
234
- *
235
- * Delegate lets you listen on multiple values at once. The following listens
236
- * for first and last name changes:
237
- *
238
- * var o = new can.Observe({
239
- * name : {first: "Justin", last: "Meyer"}
240
- * })
241
- *
242
- * o.bind("name.first,name.last",
243
- * "set",
244
- * function(ev,newVal,oldVal,from){
245
- *
246
- * })
247
- *
248
- * ## Listening when properties are a particular value
249
- *
250
- * Delegate lets you listen when a property is __set__ to a specific value:
251
- *
252
- * var o = new can.Observe({
253
- * name : "Justin"
254
- * })
255
- *
256
- * o.bind("name=Brian",
257
- * "set",
258
- * function(ev,newVal,oldVal,from){
259
- *
260
- * })
261
- *
262
- * @param {String} selector The attributes you want to listen for changes in.
263
- *
264
- * Selector should be the property or
265
- * property names of the element you are searching. Examples:
266
- *
267
- * "name" - listens to the "name" property changing
268
- * "name, address" - listens to "name" or "address" changing
269
- * "name address" - listens to "name" or "address" changing
270
- * "address.*" - listens to property directly in address
271
- * "address.**" - listens to any property change in address
272
- * "foo=bar" - listens when foo is "bar"
273
- *
274
- * @param {String} event The event name. One of ("set","add","remove","change")
275
- * @param {Function} handler(ev,newVal,oldVal,prop) The callback handler
276
- * called with:
277
- *
278
- * - newVal - the new value set on the observe
279
- * - oldVal - the old value set on the observe
280
- * - prop - the prop name that was changed
281
- *
282
- * @return {jQuery.Delegate} the delegate for chaining
283
- */
284
- delegate : function(selector, event, handler){
131
+
132
+ can.extend(can.Observe.prototype, {
133
+
134
+ delegate: function (selector, event, handler) {
285
135
  selector = can.trim(selector);
286
136
  var delegates = this._observe_delegates || (this._observe_delegates = []),
287
- attrs = [];
288
-
289
- // split selector by spaces
290
- selector.replace(/([^\s=]+)=?([^\s]+)?/g, function(whole, attr, value){
291
- attrs.push({
292
- // the attribute name
293
- attr: attr,
294
- // the attribute's pre-split names (for speed)
295
- parts: attr.split('.'),
296
- // the value associated with this prop
297
- value: value
298
- })
299
- });
300
-
137
+ attrs = [],
138
+ selectorRegex = /([^\s=,]+)(?:=("[^",]*"|'[^',]*'|[^\s"',]*))?(,?)\s*/g,
139
+ matches;
140
+
141
+ // parse each property in the selector
142
+ while (matches = selectorRegex.exec(selector)) {
143
+ // we need to do a little doctoring to make up for the quotes.
144
+ if (matches[2] && $.inArray(matches[2].substr(0, 1), ['"', "'"]) >= 0) {
145
+ matches[2] = matches[2].substr(1, -1);
146
+ }
147
+
148
+ attrs.push({
149
+ // the attribute name
150
+ attr: matches[1],
151
+ // the attribute name, pre-split for speed
152
+ parts: matches[1].split('.'),
153
+ // the value associated with this property (if there was one given)
154
+ value: matches[2],
155
+ // whether this selector combines with the one after it with AND or OR
156
+ or: matches[3] === ','
157
+ });
158
+ }
159
+
301
160
  // delegates has pre-processed info about the event
302
161
  delegates.push({
303
162
  // the attrs name for unbinding
304
- selector : selector,
163
+ selector: selector,
305
164
  // an object of attribute names and values {type: 'recipe',id: undefined}
306
165
  // undefined means a value was not defined
307
- attrs : attrs,
308
- callback : handler,
166
+ attrs: attrs,
167
+ callback: handler,
309
168
  event: event
310
169
  });
311
- if(delegates.length === 1){
312
- this.bind("change",delegate)
170
+ if (delegates.length === 1) {
171
+ this.bind("change", delegate)
313
172
  }
314
173
  return this;
315
174
  },
316
- /**
317
- * @function can.Observe.prototype.undelegate
318
- * @parent can.Observe.delegate
319
- *
320
- * `undelegate( selector, event, handler )` removes a delegated event handler from an observe.
321
- *
322
- * observe.undelegate("name","set", handler )
323
- *
324
- * @param {String} selector the attribute name of the object you want to undelegate from.
325
- * @param {String} event the event name
326
- * @param {Function} handler the callback handler
327
- * @return {jQuery.Delegate} the delegate for chaining
328
- */
329
- undelegate : function(selector, event, handler){
175
+
176
+ undelegate: function (selector, event, handler) {
330
177
  selector = can.trim(selector);
331
-
332
- var i =0,
178
+
179
+ var i = 0,
333
180
  delegates = this._observe_delegates || [],
334
181
  delegateOb;
335
- if(selector){
336
- while(i < delegates.length){
182
+ if (selector) {
183
+ while (i < delegates.length) {
337
184
  delegateOb = delegates[i];
338
- if( delegateOb.callback === handler ||
339
- (!handler && delegateOb.selector === selector) ){
185
+ if (delegateOb.callback === handler || (!handler && delegateOb.selector === selector)) {
340
186
  delegateOb.undelegated = true;
341
- delegates.splice(i,1)
187
+ delegates.splice(i, 1)
342
188
  } else {
343
189
  i++;
344
190
  }
@@ -347,13 +193,14 @@
347
193
  // remove all delegates
348
194
  delegates = [];
349
195
  }
350
- if(!delegates.length){
196
+ if (!delegates.length) {
351
197
  //can.removeData(this, "_observe_delegates");
352
- this.unbind("change",delegate)
198
+ this.unbind("change", delegate)
353
199
  }
354
200
  return this;
355
201
  }
356
202
  });
357
203
  // add helpers for testing ..
358
204
  can.Observe.prototype.delegate.matches = matches;
359
- })(this.can, this )
205
+
206
+ })(can, this);
@@ -1,58 +1,59 @@
1
- (function(can, window, undefined){
2
-
3
- /**
4
- * Like [can.camelize|camelize], but the first part is also capitalized
5
- * @param {String} s
6
- * @return {String} the classized string
7
- */
8
- can.classize = function( s , join) {
9
- // this can be moved out ..
10
- // used for getter setter
11
- var parts = s.split(can.undHash),
12
- i = 0;
13
- for (; i < parts.length; i++ ) {
14
- parts[i] = can.capitalize(parts[i]);
1
+ /*
2
+ * CanJS - 1.1.2 (2012-11-28)
3
+ * http://canjs.us/
4
+ * Copyright (c) 2012 Bitovi
5
+ * Licensed MIT
6
+ */
7
+ (function (can, window, undefined) {
8
+ // ## can/observe/setter/setter.js
9
+ can.classize = function (s, join) {
10
+ // this can be moved out ..
11
+ // used for getter setter
12
+ var parts = s.split(can.undHash),
13
+ i = 0;
14
+ for (; i < parts.length; i++) {
15
+ parts[i] = can.capitalize(parts[i]);
16
+ }
17
+
18
+ return parts.join(join || '');
15
19
  }
16
20
 
17
- return parts.join(join || '');
18
- }
19
-
20
- var classize = can.classize,
21
- proto = can.Observe.prototype,
22
- old = proto.__set;
23
-
24
- proto.__set = function(prop, value, current, success, error){
25
- // check if there's a setter
26
- var cap = classize(prop),
27
- setName = "set" + cap,
28
- errorCallback = function( errors ) {
29
- var stub = error && error.call(self, errors);
30
-
31
- // if 'setter' is on the page it will trigger
32
- // the error itself and we dont want to trigger
33
- // the event twice. :)
34
- if(stub !== false){
35
- can.trigger(self, "error", [prop, errors], true);
36
- }
37
-
38
- return false;
39
- },
40
- self = this;
41
-
42
- // if we have a setter
43
- if ( this[setName] &&
21
+ var classize = can.classize,
22
+ proto = can.Observe.prototype,
23
+ old = proto.__set;
24
+
25
+ proto.__set = function (prop, value, current, success, error) {
26
+ // check if there's a setter
27
+ var cap = classize(prop),
28
+ setName = "set" + cap,
29
+ errorCallback = function (errors) {
30
+ var stub = error && error.call(self, errors);
31
+
32
+ // if 'setter' is on the page it will trigger
33
+ // the error itself and we dont want to trigger
34
+ // the event twice. :)
35
+ if (stub !== false) {
36
+ can.trigger(self, "error", [prop, errors], true);
37
+ }
38
+
39
+ return false;
40
+ },
41
+ self = this;
42
+
43
+ // if we have a setter
44
+ if (this[setName] &&
44
45
  // call the setter, if returned value is undefined,
45
46
  // this means the setter is async so we
46
47
  // do not call update property and return right away
47
- ( value = this[setName](value,
48
- function(){ old.call(self,prop, value, current, success, errorCallback) },
49
- errorCallback ) ) === undefined ) {
50
- return;
51
- }
52
-
53
- old.call(self,prop, value, current, success, errorCallback);
54
-
55
- return this;
56
- };
48
+ (value = this[setName](value, function () {
49
+ old.call(self, prop, value, current, success, errorCallback)
50
+ }, errorCallback)) === undefined) {
51
+ return;
52
+ }
53
+
54
+ old.call(self, prop, value, current, success, errorCallback);
55
+
56
+ return this;
57
+ };
57
58
 
58
- })(this.can, this )
59
+ })(can, this);