canjs-rails 1.1.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
metadata CHANGED
@@ -1,22 +1,20 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: canjs-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
5
- prerelease:
4
+ version: 2.0.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Craig Wickesser
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-11-29 00:00:00.000000000 Z
11
+ date: 2013-10-18 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: railties
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ! '>='
17
+ - - '>='
20
18
  - !ruby/object:Gem::Version
21
19
  version: 3.2.0
22
20
  - - <
@@ -25,9 +23,8 @@ dependencies:
25
23
  type: :runtime
26
24
  prerelease: false
27
25
  version_requirements: !ruby/object:Gem::Requirement
28
- none: false
29
26
  requirements:
30
- - - ! '>='
27
+ - - '>='
31
28
  - !ruby/object:Gem::Version
32
29
  version: 3.2.0
33
30
  - - <
@@ -36,7 +33,6 @@ dependencies:
36
33
  - !ruby/object:Gem::Dependency
37
34
  name: thor
38
35
  requirement: !ruby/object:Gem::Requirement
39
- none: false
40
36
  requirements:
41
37
  - - ~>
42
38
  - !ruby/object:Gem::Version
@@ -44,7 +40,6 @@ dependencies:
44
40
  type: :runtime
45
41
  prerelease: false
46
42
  version_requirements: !ruby/object:Gem::Requirement
47
- none: false
48
43
  requirements:
49
44
  - - ~>
50
45
  - !ruby/object:Gem::Version
@@ -59,6 +54,7 @@ files:
59
54
  - .gitignore
60
55
  - CHANGELOG.md
61
56
  - Gemfile
57
+ - Gemfile.lock
62
58
  - LICENSE
63
59
  - README.md
64
60
  - Rakefile
@@ -67,43 +63,28 @@ files:
67
63
  - lib/canjs/rails.rb
68
64
  - lib/canjs/rails/engine.rb
69
65
  - lib/canjs/rails/version.rb
70
- - vendor/assets/javascripts/can.construct.proxy.js
71
- - vendor/assets/javascripts/can.construct.super.js
72
- - vendor/assets/javascripts/can.control.plugin.js
73
- - vendor/assets/javascripts/can.control.view.js
74
- - vendor/assets/javascripts/can.fixture.js
75
66
  - vendor/assets/javascripts/can.jquery.js
76
- - vendor/assets/javascripts/can.jquery.min.js
77
- - vendor/assets/javascripts/can.observe.attributes.js
78
- - vendor/assets/javascripts/can.observe.backup.js
79
- - vendor/assets/javascripts/can.observe.delegate.js
80
- - vendor/assets/javascripts/can.observe.setter.js
81
- - vendor/assets/javascripts/can.observe.validations.js
82
- - vendor/assets/javascripts/can.view.modifiers.js
83
- - vendor/assets/javascripts/can.view.mustache.js
84
- - vendor/assets/javascripts/download_canjs.sh
85
67
  homepage: https://github.com/mindscratch/canjs-rails
86
68
  licenses: []
69
+ metadata: {}
87
70
  post_install_message:
88
71
  rdoc_options: []
89
72
  require_paths:
90
73
  - lib
91
74
  required_ruby_version: !ruby/object:Gem::Requirement
92
- none: false
93
75
  requirements:
94
- - - ! '>='
76
+ - - '>='
95
77
  - !ruby/object:Gem::Version
96
78
  version: '0'
97
79
  required_rubygems_version: !ruby/object:Gem::Requirement
98
- none: false
99
80
  requirements:
100
- - - ! '>='
81
+ - - '>='
101
82
  - !ruby/object:Gem::Version
102
83
  version: 1.3.6
103
84
  requirements: []
104
85
  rubyforge_project: canjs-rails
105
- rubygems_version: 1.8.24
86
+ rubygems_version: 2.1.5
106
87
  signing_key:
107
- specification_version: 3
88
+ specification_version: 4
108
89
  summary: Use CanJS with Rails 3.1+
109
90
  test_files: []
@@ -1,61 +0,0 @@
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/construct/proxy/proxy.js
9
- var isFunction = can.isFunction,
10
- isArray = can.isArray,
11
- makeArray = can.makeArray,
12
-
13
- proxy = function (funcs) {
14
-
15
- //args that should be curried
16
- var args = makeArray(arguments),
17
- self;
18
-
19
- // get the functions to callback
20
- funcs = args.shift();
21
-
22
- // if there is only one function, make funcs into an array
23
- if (!isArray(funcs)) {
24
- funcs = [funcs];
25
- }
26
-
27
- // keep a reference to us in self
28
- self = this;
29
-
30
-
31
- return function class_cb() {
32
- // add the arguments after the curried args
33
- var cur = args.concat(makeArray(arguments)),
34
- isString, length = funcs.length,
35
- f = 0,
36
- func;
37
-
38
- // go through each function to call back
39
- for (; f < length; f++) {
40
- func = funcs[f];
41
- if (!func) {
42
- continue;
43
- }
44
-
45
- // set called with the name of the function on self (this is how this.view works)
46
- isString = typeof func == "string";
47
-
48
- // call the function
49
- cur = (isString ? self[func] : func).apply(self, cur || []);
50
-
51
- // pass the result to the next function (if there is a next function)
52
- if (f < length - 1) {
53
- cur = !isArray(cur) || cur._use_call ? [cur] : cur
54
- }
55
- }
56
- return cur;
57
- }
58
- }
59
- can.Construct.proxy = can.Construct.prototype.proxy = proxy;
60
-
61
- })(can, this);
@@ -1,48 +0,0 @@
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/construct/super/super.js
9
- // tests if we can get super in .toString()
10
- var isFunction = can.isFunction,
11
-
12
- fnTest = /xyz/.test(function () {
13
- xyz;
14
- }) ? /\b_super\b/ : /.*/;
15
-
16
- // overwrites a single property so it can still call super
17
- can.Construct._overwrite = function (addTo, base, name, val) {
18
- // Check if we're overwriting an existing function
19
- addTo[name] = isFunction(val) && isFunction(base[name]) && fnTest.test(val) ? (function (name, fn) {
20
- return function () {
21
- var tmp = this._super,
22
- ret;
23
-
24
- // Add a new ._super() method that is the same method
25
- // but on the super-class
26
- this._super = base[name];
27
-
28
- // The method only need to be bound temporarily, so we
29
- // remove it when we're done executing
30
- ret = fn.apply(this, arguments);
31
- this._super = tmp;
32
- return ret;
33
- };
34
- })(name, val) : val;
35
- }
36
- // overwrites an object with methods, sets up _super
37
- // newProps - new properties
38
- // oldProps - where the old properties might be
39
- // addTo - what we are adding to
40
- can.Construct._inherit = function (newProps, oldProps, addTo) {
41
- addTo = addTo || newProps
42
- for (var name in newProps) {
43
- can.Construct._overwrite(addTo, oldProps, name, newProps[name]);
44
- }
45
- }
46
-
47
-
48
- })(can, this);
@@ -1,108 +0,0 @@
1
- /*
2
- * CanJS - 1.1.2 (2012-11-28)
3
- * http://canjs.us/
4
- * Copyright (c) 2012 Bitovi
5
- * Licensed MIT
6
- */
7
- (function (window, $, can, undefined) {
8
- // ## can/control/plugin/plugin.js
9
- //used to determine if a control instance is one of controllers
10
- //controllers can be strings or classes
11
- var i, isAControllerOf = function (instance, controllers) {
12
- for (i = 0; i < controllers.length; i++) {
13
- if (typeof controllers[i] == 'string' ? instance.constructor._shortName == controllers[i] : instance instanceof controllers[i]) {
14
- return true;
15
- }
16
- }
17
- return false;
18
- },
19
- makeArray = can.makeArray,
20
- old = can.Control.setup;
21
-
22
- can.Control.setup = function () {
23
- // if you didn't provide a name, or are control, don't do anything
24
- if (this !== can.Control) {
25
-
26
-
27
- var pluginName = this.pluginName || this._fullName;
28
-
29
- // create jQuery plugin
30
- if (pluginName !== 'can_control') {
31
- this.plugin(pluginName);
32
- }
33
-
34
- old.apply(this, arguments);
35
- }
36
- };
37
-
38
- $.fn.extend({
39
-
40
-
41
- controls: function () {
42
- var controllerNames = makeArray(arguments),
43
- instances = [],
44
- controls, c, cname;
45
- //check if arguments
46
- this.each(function () {
47
-
48
- controls = can.$(this).data("controls");
49
- if (!controls) {
50
- return;
51
- }
52
- for (var i = 0; i < controls.length; i++) {
53
- c = controls[i];
54
- if (!controllerNames.length || isAControllerOf(c, controllerNames)) {
55
- instances.push(c);
56
- }
57
- }
58
- });
59
- return instances;
60
- },
61
-
62
-
63
- control: function (control) {
64
- return this.controls.apply(this, arguments)[0];
65
- }
66
- });
67
-
68
- can.Control.plugin = function (pluginname) {
69
- var control = this;
70
-
71
- if (!$.fn[pluginname]) {
72
- $.fn[pluginname] = function (options) {
73
-
74
- var args = makeArray(arguments),
75
- //if the arg is a method on this control
76
- isMethod = typeof options == "string" && $.isFunction(control.prototype[options]),
77
- meth = args[0],
78
- returns;
79
- this.each(function () {
80
- //check if created
81
- var plugin = can.$(this).control(control);
82
-
83
- if (plugin) {
84
- if (isMethod) {
85
- // call a method on the control with the remaining args
86
- returns = plugin[meth].apply(plugin, args.slice(1));
87
- }
88
- else {
89
- // call the plugin's update method
90
- plugin.update.apply(plugin, args);
91
- }
92
- }
93
- else {
94
- //create a new control instance
95
- control.newInstance.apply(control, [this].concat(args));
96
- }
97
- });
98
- return returns !== undefined ? returns : this;
99
- };
100
- }
101
- }
102
-
103
- can.Control.prototype.update = function (options) {
104
- can.extend(this.options, options);
105
- this.on();
106
- };
107
-
108
- })(this, jQuery, can);
@@ -1,94 +0,0 @@
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/control/view/view.js
9
- var URI = steal.URI || steal.File;
10
-
11
- can.Control.getFolder = function () {
12
- return can.underscore(this.fullName.replace(/\./g, "/")).replace("/Controllers", "");
13
- };
14
-
15
- can.Control._calculatePosition = function (Class, view) {
16
- var classParts = Class.fullName.split('.'),
17
- classPartsWithoutPrefix = classParts.slice(0);
18
- classPartsWithoutPrefix.splice(0, 2), action_name = "init"; // Remove prefix (usually 2 elements)
19
- var hasControllers = (classParts.length > 2) && classParts[1] == 'Controllers',
20
- path = hasControllers ? can.underscore(classParts[0]) : can.underscore(classParts.join("/")),
21
- controller_name = can.underscore(classPartsWithoutPrefix.join('/')).toLowerCase(),
22
- suffix = (typeof view == "string" && /\.[\w\d]+$/.test(view)) ? "" : can.view.ext;
23
-
24
- //calculate view
25
- if (typeof view == "string") {
26
- if (view.substr(0, 2) == "//") { //leave where it is
27
- } else {
28
- view = "//" + URI(path).join('views/' + (view.indexOf('/') !== -1 ? view : (hasControllers ? controller_name + '/' : "") + view)) + suffix;
29
- }
30
- } else if (!view) {
31
- view = "//" + URI(path).join('views/' + (hasControllers ? controller_name + '/' : "") + action_name.replace(/\.|#/g, '').replace(/ /g, '_')) + suffix;
32
- }
33
- return view;
34
- };
35
-
36
- var calculateHelpers = function (myhelpers) {
37
- var helpers = {};
38
- if (myhelpers) {
39
- if (can.isArray(myhelpers)) {
40
- for (var h = 0; h < myhelpers.length; h++) {
41
- can.extend(helpers, myhelpers[h]);
42
- }
43
- }
44
- else {
45
- can.extend(helpers, myhelpers);
46
- }
47
- } else {
48
- if (this._default_helpers) {
49
- helpers = this._default_helpers;
50
- }
51
-
52
- //load from name
53
- var current = window;
54
- var parts = this.constructor.fullName.split(/\./);
55
- for (var i = 0; i < parts.length; i++) {
56
- if (current) {
57
- if (typeof current.Helpers == 'object') {
58
- can.extend(helpers, current.Helpers);
59
- }
60
- current = current[parts[i]];
61
- }
62
- }
63
-
64
- if (current && typeof current.Helpers == 'object') {
65
- can.extend(helpers, current.Helpers);
66
- }
67
-
68
- this._default_helpers = helpers;
69
- }
70
- return helpers;
71
- };
72
-
73
- can.Control.prototype.view = function (view, data, myhelpers) {
74
- //shift args if no view is provided
75
- if (typeof view != "string" && !myhelpers) {
76
- myhelpers = data;
77
- data = view;
78
- view = null;
79
- }
80
-
81
- //guess from controller name
82
- view = can.Control._calculatePosition(this.constructor, view, this.called);
83
-
84
- //calculate data
85
- data = data || this;
86
-
87
- //calculate helpers
88
- var helpers = calculateHelpers.call(this, myhelpers);
89
-
90
- return can.view(view, data, helpers); //what about controllers in other folders?
91
- };
92
-
93
-
94
- })(can, this);
@@ -1,727 +0,0 @@
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/util/object/object.js
9
-
10
- var isArray = can.isArray,
11
- // essentially returns an object that has all the must have comparisons ...
12
- // must haves, do not return true when provided undefined
13
- cleanSet = function (obj, compares) {
14
- var copy = can.extend({}, obj);
15
- for (var prop in copy) {
16
- var compare = compares[prop] === undefined ? compares["*"] : compares[prop];
17
- if (same(copy[prop], undefined, compare)) {
18
- delete copy[prop]
19
- }
20
- }
21
- return copy;
22
- },
23
- propCount = function (obj) {
24
- var count = 0;
25
- for (var prop in obj) count++;
26
- return count;
27
- };
28
-
29
- can.Object = {};
30
-
31
- var same = can.Object.same = function (a, b, compares, aParent, bParent, deep) {
32
- var aType = typeof a,
33
- aArray = isArray(a),
34
- comparesType = typeof compares,
35
- compare;
36
-
37
- if (comparesType == 'string' || compares === null) {
38
- compares = compareMethods[compares];
39
- comparesType = 'function'
40
- }
41
- if (comparesType == 'function') {
42
- return compares(a, b, aParent, bParent)
43
- }
44
- compares = compares || {};
45
-
46
- if (a instanceof Date) {
47
- return a === b;
48
- }
49
- if (deep === -1) {
50
- return aType === 'object' || a === b;
51
- }
52
- if (aType !== typeof b || aArray !== isArray(b)) {
53
- return false;
54
- }
55
- if (a === b) {
56
- return true;
57
- }
58
- if (aArray) {
59
- if (a.length !== b.length) {
60
- return false;
61
- }
62
- for (var i = 0; i < a.length; i++) {
63
- compare = compares[i] === undefined ? compares["*"] : compares[i]
64
- if (!same(a[i], b[i], a, b, compare)) {
65
- return false;
66
- }
67
- };
68
- return true;
69
- } else if (aType === "object" || aType === 'function') {
70
- var bCopy = can.extend({}, b);
71
- for (var prop in a) {
72
- compare = compares[prop] === undefined ? compares["*"] : compares[prop];
73
- if (!same(a[prop], b[prop], compare, a, b, deep === false ? -1 : undefined)) {
74
- return false;
75
- }
76
- delete bCopy[prop];
77
- }
78
- // go through bCopy props ... if there is no compare .. return false
79
- for (prop in bCopy) {
80
- if (compares[prop] === undefined || !same(undefined, b[prop], compares[prop], a, b, deep === false ? -1 : undefined)) {
81
- return false;
82
- }
83
- }
84
- return true;
85
- }
86
- return false;
87
- };
88
-
89
- can.Object.subsets = function (checkSet, sets, compares) {
90
- var len = sets.length,
91
- subsets = [],
92
- checkPropCount = propCount(checkSet),
93
- setLength;
94
-
95
- for (var i = 0; i < len; i++) {
96
- //check this subset
97
- var set = sets[i];
98
- if (can.Object.subset(checkSet, set, compares)) {
99
- subsets.push(set)
100
- }
101
- }
102
- return subsets;
103
- };
104
-
105
- can.Object.subset = function (subset, set, compares) {
106
- // go through set {type: 'folder'} and make sure every property
107
- // is in subset {type: 'folder', parentId :5}
108
- // then make sure that set has fewer properties
109
- // make sure we are only checking 'important' properties
110
- // in subset (ones that have to have a value)
111
- var setPropCount = 0,
112
- compares = compares || {};
113
-
114
- for (var prop in set) {
115
-
116
- if (!same(subset[prop], set[prop], compares[prop], subset, set)) {
117
- return false;
118
- }
119
- }
120
- return true;
121
- }
122
-
123
- var compareMethods = {
124
- "null": function () {
125
- return true;
126
- },
127
- i: function (a, b) {
128
- return ("" + a).toLowerCase() == ("" + b).toLowerCase()
129
- }
130
- }
131
-
132
- // ## can/util/fixture/fixture.js
133
- // Get the URL from old Steal root, new Steal config or can.fixture.rootUrl
134
- var getUrl = function (url) {
135
- if (typeof steal !== 'undefined') {
136
- if (can.isFunction(steal.config)) {
137
- return steal.config().root.mapJoin(url).toString();
138
- }
139
- return steal.root.join(url).toString();
140
- }
141
- return (can.fixture.rootUrl || '') + url;
142
- }
143
-
144
- var updateSettings = function (settings, originalOptions) {
145
- if (!can.fixture.on) {
146
- return;
147
- }
148
-
149
- //simple wrapper for logging
150
- var _logger = function (type, arr) {
151
- if (console.log.apply) {
152
- Function.prototype.call.apply(console[type], [console].concat(arr));
153
- // console[type].apply(console, arr)
154
- } else {
155
- console[type](arr)
156
- }
157
- },
158
- log = function () {
159
- if (window.console && console.log) {
160
- Array.prototype.unshift.call(arguments, 'fixture INFO:');
161
- _logger("log", Array.prototype.slice.call(arguments));
162
- }
163
- else if (window.opera && window.opera.postError) {
164
- opera.postError("fixture INFO: " + Array.prototype.join.call(arguments, ','));
165
- }
166
- }
167
-
168
- // We always need the type which can also be called method, default to GET
169
- settings.type = settings.type || settings.method || 'GET';
170
-
171
- // add the fixture option if programmed in
172
- var data = overwrite(settings);
173
-
174
- // if we don't have a fixture, do nothing
175
- if (!settings.fixture) {
176
- if (window.location.protocol === "file:") {
177
- log("ajax request to " + settings.url + ", no fixture found");
178
- }
179
- return;
180
- }
181
-
182
- //if referencing something else, update the fixture option
183
- if (typeof settings.fixture === "string" && can.fixture[settings.fixture]) {
184
- settings.fixture = can.fixture[settings.fixture];
185
- }
186
-
187
- // if a string, we just point to the right url
188
- if (typeof settings.fixture == "string") {
189
- var url = settings.fixture;
190
-
191
- if (/^\/\//.test(url)) {
192
- // this lets us use rootUrl w/o having steal...
193
- url = getUrl(settings.fixture.substr(2));
194
- }
195
-
196
- if (data) {
197
- // Template static fixture URLs
198
- url = can.sub(url, data);
199
- }
200
-
201
- delete settings.fixture;
202
-
203
-
204
-
205
- settings.url = url;
206
- settings.data = null;
207
- settings.type = "GET";
208
- if (!settings.error) {
209
- settings.error = function (xhr, error, message) {
210
- throw "fixtures.js Error " + error + " " + message;
211
- };
212
- }
213
- }
214
- else {
215
-
216
-
217
- //it's a function ... add the fixture datatype so our fixture transport handles it
218
- // TODO: make everything go here for timing and other fun stuff
219
- // add to settings data from fixture ...
220
- settings.dataTypes && settings.dataTypes.splice(0, 0, "fixture");
221
-
222
- if (data && originalOptions) {
223
- can.extend(originalOptions.data, data)
224
- }
225
- }
226
- },
227
- // A helper function that takes what's called with response
228
- // and moves some common args around to make it easier to call
229
- extractResponse = function (status, statusText, responses, headers) {
230
- // if we get response(RESPONSES, HEADERS)
231
- if (typeof status != "number") {
232
- headers = statusText;
233
- responses = status;
234
- statusText = "success"
235
- status = 200;
236
- }
237
- // if we get response(200, RESPONSES, HEADERS)
238
- if (typeof statusText != "string") {
239
- headers = responses;
240
- responses = statusText;
241
- statusText = "success";
242
- }
243
- if (status >= 400 && status <= 599) {
244
- this.dataType = "text"
245
- }
246
- return [status, statusText, extractResponses(this, responses), headers];
247
- },
248
- // If we get data instead of responses,
249
- // make sure we provide a response type that matches the first datatype (typically json)
250
- extractResponses = function (settings, responses) {
251
- var next = settings.dataTypes ? settings.dataTypes[0] : (settings.dataType || 'json');
252
- if (!responses || !responses[next]) {
253
- var tmp = {}
254
- tmp[next] = responses;
255
- responses = tmp;
256
- }
257
- return responses;
258
- };
259
-
260
- //used to check urls
261
- // check if jQuery
262
- if (can.ajaxPrefilter && can.ajaxTransport) {
263
-
264
- // the pre-filter needs to re-route the url
265
- can.ajaxPrefilter(updateSettings);
266
-
267
- can.ajaxTransport("fixture", function (s, original) {
268
- // remove the fixture from the datatype
269
- s.dataTypes.shift();
270
-
271
- //we'll return the result of the next data type
272
- var timeout, stopped = false;
273
-
274
- return {
275
- send: function (headers, callback) {
276
- // we'll immediately wait the delay time for all fixtures
277
- timeout = setTimeout(function () {
278
- // if the user wants to call success on their own, we allow it ...
279
- var success = function () {
280
- if (stopped === false) {
281
- callback.apply(null, extractResponse.apply(s, arguments));
282
- }
283
- },
284
- // get the result form the fixture
285
- result = s.fixture(original, success, headers, s);
286
- if (result !== undefined) {
287
- // make sure the result has the right dataType
288
- callback(200, "success", extractResponses(s, result), {});
289
- }
290
- }, can.fixture.delay);
291
- },
292
- abort: function () {
293
- stopped = true;
294
- clearTimeout(timeout)
295
- }
296
- };
297
- });
298
- } else {
299
- var AJAX = can.ajax;
300
- can.ajax = function (settings) {
301
- updateSettings(settings, settings);
302
- if (settings.fixture) {
303
- var timeout, d = new can.Deferred(),
304
- stopped = false;
305
-
306
- //TODO this should work with response
307
- d.getResponseHeader = function () {}
308
-
309
- // call success and fail
310
- d.then(settings.success, settings.fail);
311
-
312
- // abort should stop the timeout and calling success
313
- d.abort = function () {
314
- clearTimeout(timeout);
315
- stopped = true;
316
- d.reject(d)
317
- }
318
- // set a timeout that simulates making a request ....
319
- timeout = setTimeout(function () {
320
- // if the user wants to call success on their own, we allow it ...
321
- var success = function () {
322
- var response = extractResponse.apply(settings, arguments),
323
- status = response[0];
324
-
325
- if ((status >= 200 && status < 300 || status === 304) && stopped === false) {
326
- d.resolve(response[2][settings.dataType])
327
- } else {
328
- // TODO probably resolve better
329
- d.reject(d, 'error', response[1]);
330
- }
331
- },
332
- // get the result form the fixture
333
- result = settings.fixture(settings, success, settings.headers, settings);
334
- if (result !== undefined) {
335
- d.resolve(result)
336
- }
337
- }, can.fixture.delay);
338
-
339
- return d;
340
- } else {
341
- return AJAX(settings);
342
- }
343
- }
344
- }
345
-
346
- var typeTest = /^(script|json|text|jsonp)$/,
347
- // a list of 'overwrite' settings object
348
- overwrites = [],
349
- // returns the index of an overwrite function
350
- find = function (settings, exact) {
351
- for (var i = 0; i < overwrites.length; i++) {
352
- if ($fixture._similar(settings, overwrites[i], exact)) {
353
- return i;
354
- }
355
- }
356
- return -1;
357
- },
358
- // overwrites the settings fixture if an overwrite matches
359
- overwrite = function (settings) {
360
- var index = find(settings);
361
- if (index > -1) {
362
- settings.fixture = overwrites[index].fixture;
363
- return $fixture._getData(overwrites[index].url, settings.url)
364
- }
365
-
366
- },
367
-
368
- getId = function (settings) {
369
- var id = settings.data.id;
370
-
371
- if (id === undefined && typeof settings.data === "number") {
372
- id = settings.data;
373
- }
374
-
375
-
376
-
377
- if (id === undefined) {
378
- settings.url.replace(/\/(\d+)(\/|$|\.)/g, function (all, num) {
379
- id = num;
380
- });
381
- }
382
-
383
- if (id === undefined) {
384
- id = settings.url.replace(/\/(\w+)(\/|$|\.)/g, function (all, num) {
385
- if (num != 'update') {
386
- id = num;
387
- }
388
- })
389
- }
390
-
391
- if (id === undefined) { // if still not set, guess a random number
392
- id = Math.round(Math.random() * 1000)
393
- }
394
-
395
- return id;
396
- };
397
-
398
-
399
- var $fixture = can.fixture = function (settings, fixture) {
400
- // if we provide a fixture ...
401
- if (fixture !== undefined) {
402
- if (typeof settings == 'string') {
403
- // handle url strings
404
- var matches = settings.match(/(GET|POST|PUT|DELETE) (.+)/i);
405
- if (!matches) {
406
- settings = {
407
- url: settings
408
- };
409
- } else {
410
- settings = {
411
- url: matches[2],
412
- type: matches[1]
413
- };
414
- }
415
-
416
- }
417
-
418
- //handle removing. An exact match if fixture was provided, otherwise, anything similar
419
- var index = find(settings, !! fixture);
420
- if (index > -1) {
421
- overwrites.splice(index, 1)
422
- }
423
- if (fixture == null) {
424
- return
425
- }
426
- settings.fixture = fixture;
427
- overwrites.push(settings)
428
- } else {
429
- can.each(settings, function (fixture, url) {
430
- $fixture(url, fixture);
431
- })
432
- }
433
- };
434
- var replacer = can.replacer;
435
-
436
- can.extend(can.fixture, {
437
- // given ajax settings, find an overwrite
438
- _similar: function (settings, overwrite, exact) {
439
- if (exact) {
440
- return can.Object.same(settings, overwrite, {
441
- fixture: null
442
- })
443
- } else {
444
- return can.Object.subset(settings, overwrite, can.fixture._compare)
445
- }
446
- },
447
- _compare: {
448
- url: function (a, b) {
449
- return !!$fixture._getData(b, a)
450
- },
451
- fixture: null,
452
- type: "i"
453
- },
454
- // gets data from a url like "/todo/{id}" given "todo/5"
455
- _getData: function (fixtureUrl, url) {
456
- var order = [],
457
- fixtureUrlAdjusted = fixtureUrl.replace('.', '\\.').replace('?', '\\?'),
458
- res = new RegExp(fixtureUrlAdjusted.replace(replacer, function (whole, part) {
459
- order.push(part)
460
- return "([^\/]+)"
461
- }) + "$").exec(url),
462
- data = {};
463
-
464
- if (!res) {
465
- return null;
466
- }
467
- res.shift();
468
- can.each(order, function (name) {
469
- data[name] = res.shift()
470
- })
471
- return data;
472
- },
473
-
474
- make: function (types, count, make, filter) {
475
-
476
- var items = [],
477
- // TODO: change this to a hash
478
- findOne = function (id) {
479
- for (var i = 0; i < items.length; i++) {
480
- if (id == items[i].id) {
481
- return items[i];
482
- }
483
- }
484
- },
485
- methods = {};
486
-
487
- if (typeof types === "string") {
488
- types = [types + "s", types]
489
- } else if (!can.isArray(types)) {
490
- filter = make;
491
- make = count;
492
- count = types;
493
- }
494
-
495
- // make all items
496
- can.extend(methods, {
497
- findAll: function (settings) {
498
- //copy array of items
499
- var retArr = items.slice(0);
500
- settings.data = settings.data || {};
501
- //sort using order
502
- //order looks like ["age ASC","gender DESC"]
503
- can.each((settings.data.order || []).slice(0).reverse(), function (name) {
504
- var split = name.split(" ");
505
- retArr = retArr.sort(function (a, b) {
506
- if (split[1].toUpperCase() !== "ASC") {
507
- if (a[split[0]] < b[split[0]]) {
508
- return 1;
509
- } else if (a[split[0]] == b[split[0]]) {
510
- return 0
511
- } else {
512
- return -1;
513
- }
514
- }
515
- else {
516
- if (a[split[0]] < b[split[0]]) {
517
- return -1;
518
- } else if (a[split[0]] == b[split[0]]) {
519
- return 0
520
- } else {
521
- return 1;
522
- }
523
- }
524
- });
525
- });
526
-
527
- //group is just like a sort
528
- can.each((settings.data.group || []).slice(0).reverse(), function (name) {
529
- var split = name.split(" ");
530
- retArr = retArr.sort(function (a, b) {
531
- return a[split[0]] > b[split[0]];
532
- });
533
- });
534
-
535
- var offset = parseInt(settings.data.offset, 10) || 0,
536
- limit = parseInt(settings.data.limit, 10) || (items.length - offset),
537
- i = 0;
538
-
539
- //filter results if someone added an attr like parentId
540
- for (var param in settings.data) {
541
- i = 0;
542
- if (settings.data[param] !== undefined && // don't do this if the value of the param is null (ignore it)
543
- (param.indexOf("Id") != -1 || param.indexOf("_id") != -1)) {
544
- while (i < retArr.length) {
545
- if (settings.data[param] != retArr[i][param]) {
546
- retArr.splice(i, 1);
547
- } else {
548
- i++;
549
- }
550
- }
551
- }
552
- }
553
-
554
- if (filter) {
555
- i = 0;
556
- while (i < retArr.length) {
557
- if (!filter(retArr[i], settings)) {
558
- retArr.splice(i, 1);
559
- } else {
560
- i++;
561
- }
562
- }
563
- }
564
-
565
- //return data spliced with limit and offset
566
- return {
567
- "count": retArr.length,
568
- "limit": settings.data.limit,
569
- "offset": settings.data.offset,
570
- "data": retArr.slice(offset, offset + limit)
571
- };
572
- },
573
- findOne: function (orig, response) {
574
- var item = findOne(getId(orig));
575
- response(item ? item : undefined);
576
- },
577
- update: function (orig, response) {
578
- var id = getId(orig);
579
-
580
- // TODO: make it work with non-linear ids ..
581
- can.extend(findOne(id), orig.data);
582
- response({
583
- id: getId(orig)
584
- }, {
585
- location: orig.url + "/" + getId(orig)
586
- });
587
- },
588
- destroy: function (settings) {
589
- var id = getId(settings);
590
- for (var i = 0; i < items.length; i++) {
591
- if (items[i].id == id) {
592
- items.splice(i, 1);
593
- break;
594
- }
595
- }
596
-
597
- // TODO: make it work with non-linear ids ..
598
- can.extend(findOne(id) || {}, settings.data);
599
- return {};
600
- },
601
- create: function (settings, response) {
602
- var item = make(items.length, items);
603
-
604
- can.extend(item, settings.data);
605
-
606
- if (!item.id) {
607
- item.id = items.length;
608
- }
609
-
610
- items.push(item);
611
- var id = item.id || parseInt(Math.random() * 100000, 10);
612
- response({
613
- id: id
614
- }, {
615
- location: settings.url + "/" + id
616
- })
617
- }
618
- });
619
-
620
- for (var i = 0; i < (count); i++) {
621
- //call back provided make
622
- var item = make(i, items);
623
-
624
- if (!item.id) {
625
- item.id = i;
626
- }
627
- items.push(item);
628
- }
629
-
630
- // if we have types given add them to can.fixture
631
- if (can.isArray(types)) {
632
- can.fixture["~" + types[0]] = items;
633
- can.fixture["-" + types[0]] = methods.findAll;
634
- can.fixture["-" + types[1]] = methods.findOne;
635
- can.fixture["-" + types[1] + "Update"] = methods.update;
636
- can.fixture["-" + types[1] + "Destroy"] = methods.destroy;
637
- can.fixture["-" + types[1] + "Create"] = methods.create;
638
- }
639
-
640
- return can.extend({
641
- getId: getId,
642
- find: function (settings) {
643
- return findOne(getId(settings));
644
- }
645
- }, methods);
646
- },
647
-
648
- rand: function (arr, min, max) {
649
- if (typeof arr == 'number') {
650
- if (typeof min == 'number') {
651
- return arr + Math.floor(Math.random() * (min - arr));
652
- } else {
653
- return Math.floor(Math.random() * arr);
654
- }
655
-
656
- }
657
- var rand = arguments.callee;
658
- // get a random set
659
- if (min === undefined) {
660
- return rand(arr, rand(arr.length + 1))
661
- }
662
- // get a random selection of arr
663
- var res = [];
664
- arr = arr.slice(0);
665
- // set max
666
- if (!max) {
667
- max = min;
668
- }
669
- //random max
670
- max = min + Math.round(rand(max - min))
671
- for (var i = 0; i < max; i++) {
672
- res.push(arr.splice(rand(arr.length), 1)[0])
673
- }
674
- return res;
675
- },
676
-
677
- xhr: function (xhr) {
678
- return can.extend({}, {
679
- abort: can.noop,
680
- getAllResponseHeaders: function () {
681
- return "";
682
- },
683
- getResponseHeader: function () {
684
- return "";
685
- },
686
- open: can.noop,
687
- overrideMimeType: can.noop,
688
- readyState: 4,
689
- responseText: "",
690
- responseXML: null,
691
- send: can.noop,
692
- setRequestHeader: can.noop,
693
- status: 200,
694
- statusText: "OK"
695
- }, xhr);
696
- },
697
-
698
- on: true
699
- });
700
-
701
- can.fixture.delay = 200;
702
-
703
-
704
- can.fixture.rootUrl = getUrl('');
705
-
706
- can.fixture["-handleFunction"] = function (settings) {
707
- if (typeof settings.fixture === "string" && can.fixture[settings.fixture]) {
708
- settings.fixture = can.fixture[settings.fixture];
709
- }
710
- if (typeof settings.fixture == "function") {
711
- setTimeout(function () {
712
- if (settings.success) {
713
- settings.success.apply(null, settings.fixture(settings, "success"));
714
- }
715
- if (settings.complete) {
716
- settings.complete.apply(null, settings.fixture(settings, "complete"));
717
- }
718
- }, can.fixture.delay);
719
- return true;
720
- }
721
- return false;
722
- };
723
-
724
- //Expose this for fixture debugging
725
- can.fixture.overwrites = overwrites;
726
-
727
- })(can, this);