canjs-rails 1.1.2 → 2.0.0

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