canjs-rails 0.1.0 → 1.1.2

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.
@@ -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);