gokart 0.0.3 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- data/assets/Guardfile +7 -3
- data/assets/config.rb +1 -1
- data/assets/src/www/app/scripts/application.js.coffee +5 -0
- data/assets/src/www/app/scripts/main.js.coffee +9 -0
- data/assets/src/www/app/{coffee/libs → scripts/utilities}/deferred.js.coffee +4 -10
- data/assets/src/www/app/{coffee/libs → scripts/utilities}/logger.js.coffee +7 -4
- data/assets/src/www/app/{coffee/helpers → scripts/utilities}/properties.js.coffee +5 -3
- data/assets/src/www/app/scripts/utilities/require.js +69 -0
- data/assets/src/www/spec/all-spec.js +11 -0
- data/assets/src/www/spec/helpers/mocks.coffee +8 -0
- data/assets/{spec/javascripts → src/www/spec}/support/jasmine.yml +2 -4
- data/assets/{spec/javascripts → src/www/spec}/support/jasmine_config.rb +0 -0
- data/assets/{spec/javascripts → src/www/spec}/support/jasmine_runner.rb +0 -0
- data/assets/src/www/spec/utilities/deferred-spec.coffee +202 -0
- data/assets/src/www/spec/utilities/properties-spec.coffee +23 -0
- data/assets/src/www/spec/utilities/test-spec.js +7 -0
- data/assets/src/www/vendor/js/backbone-min.js +40 -0
- data/assets/tasks/www.rake +34 -33
- data/lib/gokart/base.rb +6 -3
- data/lib/gokart/environment.rb +1 -19
- data/lib/gokart/version.rb +1 -1
- metadata +47 -45
- data/assets/src/www/app/coffee/application.js.coffee +0 -6
- data/assets/src/www/app/coffee/libs/mod_loader.js.coffee +0 -44
- data/assets/src/www/app/coffee/main.js.coffee +0 -10
- data/assets/src/www/spec/coffee/deferred-spec.coffee +0 -202
- data/assets/src/www/spec/coffee/mocks.coffee +0 -137
- data/assets/src/www/spec/coffee/mod_loader-spec.coffee +0 -45
- data/assets/src/www/spec/coffee/properties-spec.coffee +0 -21
data/assets/Guardfile
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
load File.dirname(__FILE__) + '/config.rb'
|
4
4
|
|
5
|
-
guard 'coffeescript', :input => 'src/www/spec
|
5
|
+
guard 'coffeescript', :input => 'src/www/spec', :output => 'spec/javascripts', :hide_success => true
|
6
6
|
|
7
7
|
guard 'shell' do
|
8
8
|
watch(%r{^src/server/.+\.go$}) do
|
@@ -11,7 +11,7 @@ guard 'shell' do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
guard 'rake', :task => 'app:www:compile' do
|
14
|
-
watch(%r{^src/www/app/
|
14
|
+
watch(%r{^src/www/app/scripts/.+$})
|
15
15
|
watch(%r{^src/www/app/sass/.+$})
|
16
16
|
end
|
17
17
|
|
@@ -31,7 +31,11 @@ guard 'rake', :task => 'app:www:partials' do
|
|
31
31
|
watch(%r{^src/www/app/partials/.+$})
|
32
32
|
end
|
33
33
|
|
34
|
+
guard 'rake', :task => 'app:www:spec' do
|
35
|
+
watch(%r{^src/www/spec/.+$})
|
36
|
+
end
|
37
|
+
|
34
38
|
guard 'livereload', :apply_js_live => false do
|
35
|
-
watch(%r{bin/assets/www/
|
39
|
+
watch(%r{bin/assets/www-debug/js/.+$})
|
36
40
|
watch(%r{spec/javascripts/.+$})
|
37
41
|
end
|
data/assets/config.rb
CHANGED
@@ -1,6 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
context = @
|
1
|
+
define 'utilities/deferred', [], ->
|
4
2
|
|
5
3
|
class Promise
|
6
4
|
constructor: ->
|
@@ -11,12 +9,12 @@ modLoader.define 'libs/deferred', (require, exports)=>
|
|
11
9
|
|
12
10
|
_doDone: (data)->
|
13
11
|
for done in @_dones
|
14
|
-
done.apply(
|
12
|
+
done.apply(null, data)
|
15
13
|
return
|
16
14
|
|
17
15
|
_doFail: (data)->
|
18
16
|
for fail in @_fails
|
19
|
-
fail.apply(
|
17
|
+
fail.apply(null, data)
|
20
18
|
return
|
21
19
|
|
22
20
|
doFinish: (isResolved, data)->
|
@@ -85,8 +83,4 @@ modLoader.define 'libs/deferred', (require, exports)=>
|
|
85
83
|
@_finish(_pending.isResolved, _pending.data) if _pending?
|
86
84
|
return promise
|
87
85
|
|
88
|
-
|
89
|
-
exports.create = ->
|
90
|
-
return new Deferred()
|
91
|
-
|
92
|
-
return
|
86
|
+
return Deferred
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
define 'utilities/logger', [], ->
|
2
2
|
|
3
3
|
@appLoggerInstance = null
|
4
4
|
|
@@ -30,11 +30,14 @@ modLoader.define 'libs/logger', (require,exports)->
|
|
30
30
|
@appLoggerInstance = logger()
|
31
31
|
return
|
32
32
|
|
33
|
-
|
33
|
+
getInstance = (name) =>
|
34
34
|
_initLogger() if !@appLoggerInstance
|
35
35
|
return @appLoggerInstance
|
36
36
|
|
37
|
-
|
37
|
+
reset = =>
|
38
38
|
delete @appLoggerInstance
|
39
39
|
|
40
|
-
return
|
40
|
+
return {
|
41
|
+
getInstance: getInstance
|
42
|
+
reset: reset
|
43
|
+
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
define 'utilities/properties', [], ->
|
2
2
|
|
3
3
|
_buildProp = (cont, propStore, isStatic)->
|
4
4
|
return (value) ->
|
@@ -9,11 +9,13 @@ modLoader.define 'helpers/properties', (require,exports)->
|
|
9
9
|
|
10
10
|
return cont[propStore]
|
11
11
|
|
12
|
-
|
12
|
+
add = (cont, props)->
|
13
13
|
for own prop,rules of props
|
14
14
|
propStore = '__auto__'+prop
|
15
15
|
cont[propStore] = if rules.value != undefined then rules.value else null
|
16
16
|
cont[prop] = _buildProp(cont, propStore, rules.static)
|
17
17
|
return
|
18
18
|
|
19
|
-
return
|
19
|
+
return {
|
20
|
+
add: add
|
21
|
+
}
|
@@ -0,0 +1,69 @@
|
|
1
|
+
/**
|
2
|
+
* Builds a module loader tool which will resolve dependencies.
|
3
|
+
*/
|
4
|
+
(function requireModule(context) {
|
5
|
+
var modules = {};
|
6
|
+
|
7
|
+
/**
|
8
|
+
*
|
9
|
+
* @param {String} name
|
10
|
+
* @return {Object}
|
11
|
+
*
|
12
|
+
* @function
|
13
|
+
*/
|
14
|
+
context.require = function requireFunc(name) {
|
15
|
+
var mod = modules[name];
|
16
|
+
if (!mod) {
|
17
|
+
console.error('Module '+name+' was not defined');
|
18
|
+
return null;
|
19
|
+
}
|
20
|
+
|
21
|
+
if (mod.built) {
|
22
|
+
return mod.exports;
|
23
|
+
}
|
24
|
+
|
25
|
+
var dependencies = mod.dependencies,
|
26
|
+
numDep = dependencies.length;
|
27
|
+
var builtDep = [];
|
28
|
+
for (var i = 0; i < numDep; i++) {
|
29
|
+
var dep = dependencies[i];
|
30
|
+
builtDep.push(requireFunc(dep));
|
31
|
+
}
|
32
|
+
if (mod.builder) {
|
33
|
+
mod.exports = mod.builder.apply(null, builtDep);
|
34
|
+
}
|
35
|
+
mod.built = true;
|
36
|
+
|
37
|
+
return mod.exports;
|
38
|
+
};
|
39
|
+
|
40
|
+
/**
|
41
|
+
* Adds a new module to the list of known modules. It will not be compiled yet until
|
42
|
+
* it is required. Unless the execute flag is set in the options.
|
43
|
+
*
|
44
|
+
* @param {String} name name of this module
|
45
|
+
* @param {String[]} dep list of dependency names
|
46
|
+
* @param {function} builder function taking a list of built dependencies
|
47
|
+
* @param options optional parameters to configure the require (tbd)
|
48
|
+
*
|
49
|
+
* @private
|
50
|
+
* @function
|
51
|
+
*/
|
52
|
+
context.define = function defineFunc(name, dep, builder, options) {
|
53
|
+
dep = dep || [];
|
54
|
+
options = options | {};
|
55
|
+
|
56
|
+
modules[name] = {
|
57
|
+
builder: builder,
|
58
|
+
built: false,
|
59
|
+
exports: null,
|
60
|
+
dependencies: dep || [],
|
61
|
+
options: options
|
62
|
+
};
|
63
|
+
|
64
|
+
if (options.execute) {
|
65
|
+
requireFunc(name);
|
66
|
+
}
|
67
|
+
};
|
68
|
+
|
69
|
+
})(window);
|
@@ -11,9 +11,8 @@
|
|
11
11
|
# - dist/**/*.js
|
12
12
|
#
|
13
13
|
src_files:
|
14
|
-
- js/
|
15
|
-
- js
|
16
|
-
- js/helpers/**/*.js
|
14
|
+
- "js/utilities/require.js"
|
15
|
+
- "js/**/*.js"
|
17
16
|
|
18
17
|
# stylesheets
|
19
18
|
#
|
@@ -39,7 +38,6 @@ stylesheets:
|
|
39
38
|
# - helpers/**/*.js
|
40
39
|
#
|
41
40
|
helpers:
|
42
|
-
- mocks.js
|
43
41
|
|
44
42
|
# spec_files
|
45
43
|
#
|
File without changes
|
File without changes
|
@@ -0,0 +1,202 @@
|
|
1
|
+
define 'spec/utilities/deferred', ['utilities/deferred'], (Deferred) ->
|
2
|
+
describe 'Deferred Test', ->
|
3
|
+
it 'should be able to create a deferred object, and get a promise from it', ->
|
4
|
+
df = new Deferred()
|
5
|
+
expect(df).toBeDefined()
|
6
|
+
|
7
|
+
promise = df.promise()
|
8
|
+
expect(promise).toBeDefined()
|
9
|
+
|
10
|
+
it 'should be able to create a deferred which will resolve a promise, synchournously', ->
|
11
|
+
df = new Deferred()
|
12
|
+
promise = df.promise()
|
13
|
+
|
14
|
+
wasFulfilled = false
|
15
|
+
promise.done ->
|
16
|
+
wasFulfilled = true
|
17
|
+
|
18
|
+
df.resolve()
|
19
|
+
|
20
|
+
waitsFor ->
|
21
|
+
return wasFulfilled
|
22
|
+
, 'promise to be fulfilled', 100
|
23
|
+
|
24
|
+
runs ->
|
25
|
+
expect(wasFulfilled).toBe(true)
|
26
|
+
|
27
|
+
it 'should be able to create a deferred which will reject a promise, synchournously', ->
|
28
|
+
df = new Deferred()
|
29
|
+
promise = df.promise()
|
30
|
+
|
31
|
+
wasRejected = false
|
32
|
+
promise.fail ->
|
33
|
+
wasRejected = true
|
34
|
+
|
35
|
+
df.reject()
|
36
|
+
|
37
|
+
waitsFor ->
|
38
|
+
return wasRejected
|
39
|
+
, 'promise to be rejected', 100
|
40
|
+
|
41
|
+
runs ->
|
42
|
+
expect(wasRejected).toBe(true)
|
43
|
+
|
44
|
+
it 'should be able to resolve a promise before the promise is created, synchournously', ->
|
45
|
+
df = new Deferred()
|
46
|
+
promise = df.promise()
|
47
|
+
|
48
|
+
df.resolve()
|
49
|
+
|
50
|
+
wasFulfilled = false
|
51
|
+
promise.done ->
|
52
|
+
wasFulfilled = true
|
53
|
+
|
54
|
+
waitsFor ->
|
55
|
+
return wasFulfilled
|
56
|
+
, 'promise to be fulfilled', 100
|
57
|
+
|
58
|
+
runs ->
|
59
|
+
expect(wasFulfilled).toBe(true)
|
60
|
+
|
61
|
+
it 'should be able to reject a promise before the promise is created, synchournously', ->
|
62
|
+
df = new Deferred()
|
63
|
+
promise = df.promise()
|
64
|
+
|
65
|
+
df.reject()
|
66
|
+
|
67
|
+
wasRejected = false
|
68
|
+
promise.fail ->
|
69
|
+
wasRejected = true
|
70
|
+
|
71
|
+
waitsFor ->
|
72
|
+
return wasRejected
|
73
|
+
, 'promise to be rejected', 100
|
74
|
+
|
75
|
+
runs ->
|
76
|
+
expect(wasRejected).toBe(true)
|
77
|
+
|
78
|
+
it 'should be able to resolve a promise with data', ->
|
79
|
+
df = new Deferred()
|
80
|
+
promise = df.promise()
|
81
|
+
|
82
|
+
df.resolve({myObj: true})
|
83
|
+
|
84
|
+
wasFulfilled = false
|
85
|
+
promise.done (obj)->
|
86
|
+
expect(obj.myObj).toBe(true)
|
87
|
+
wasFulfilled = true
|
88
|
+
|
89
|
+
|
90
|
+
waitsFor ->
|
91
|
+
return wasFulfilled
|
92
|
+
, 'promise to be fulfilled', 100
|
93
|
+
|
94
|
+
runs ->
|
95
|
+
expect(wasFulfilled).toBe(true)
|
96
|
+
|
97
|
+
it 'should be able to reject a promise with data', ->
|
98
|
+
df = new Deferred()
|
99
|
+
promise = df.promise()
|
100
|
+
|
101
|
+
df.reject({myObj: true})
|
102
|
+
|
103
|
+
wasRejected = false
|
104
|
+
promise.fail (obj)->
|
105
|
+
expect(obj.myObj).toBe(true)
|
106
|
+
wasRejected = true
|
107
|
+
|
108
|
+
|
109
|
+
waitsFor ->
|
110
|
+
return wasRejected
|
111
|
+
, 'promise to be reject', 100
|
112
|
+
|
113
|
+
runs ->
|
114
|
+
expect(wasRejected).toBe(true)
|
115
|
+
|
116
|
+
it 'should be able to resolve a promise with multile datas', ->
|
117
|
+
df = new Deferred()
|
118
|
+
promise = df.promise()
|
119
|
+
|
120
|
+
df.resolve({myObj: true}, {myObj2: true}, {myObj3: true})
|
121
|
+
|
122
|
+
wasFulfilled = false
|
123
|
+
promise.done (obj, obj2, obj3)->
|
124
|
+
expect(obj.myObj).toBe(true)
|
125
|
+
expect(obj2.myObj2).toBe(true)
|
126
|
+
expect(obj3.myObj3).toBe(true)
|
127
|
+
wasFulfilled = true
|
128
|
+
|
129
|
+
|
130
|
+
waitsFor ->
|
131
|
+
return wasFulfilled
|
132
|
+
, 'promise to be fulfilled', 100
|
133
|
+
|
134
|
+
runs ->
|
135
|
+
expect(wasFulfilled).toBe(true)
|
136
|
+
|
137
|
+
it 'should be able to reject a promise with multile datas', ->
|
138
|
+
df = new Deferred()
|
139
|
+
promise = df.promise()
|
140
|
+
|
141
|
+
df.reject({myObj: true}, {myObj2: true}, {myObj3: true})
|
142
|
+
|
143
|
+
wasRejected = false
|
144
|
+
promise.fail (obj, obj2, obj3)->
|
145
|
+
expect(obj.myObj).toBe(true)
|
146
|
+
expect(obj2.myObj2).toBe(true)
|
147
|
+
expect(obj3.myObj3).toBe(true)
|
148
|
+
wasRejected = true
|
149
|
+
|
150
|
+
|
151
|
+
waitsFor ->
|
152
|
+
return wasRejected
|
153
|
+
, 'promise to be rejected', 100
|
154
|
+
|
155
|
+
runs ->
|
156
|
+
expect(wasRejected).toBe(true)
|
157
|
+
|
158
|
+
|
159
|
+
it 'should be able to resolve a promise with data, using the then', ->
|
160
|
+
df = new Deferred()
|
161
|
+
promise = df.promise()
|
162
|
+
|
163
|
+
df.resolve({myObj: true})
|
164
|
+
|
165
|
+
wasFulfilled = false
|
166
|
+
promise.then (obj)->
|
167
|
+
expect(obj.myObj).toBe(true)
|
168
|
+
wasFulfilled = true
|
169
|
+
, (obj)->
|
170
|
+
expect('not to be called').toBe(true)
|
171
|
+
wasFulfilled = false
|
172
|
+
|
173
|
+
waitsFor ->
|
174
|
+
return wasFulfilled
|
175
|
+
, 'promise to be fulfilled', 100
|
176
|
+
|
177
|
+
runs ->
|
178
|
+
expect(wasFulfilled).toBe(true)
|
179
|
+
|
180
|
+
|
181
|
+
it 'should be able to reject a promise with data, using the then', ->
|
182
|
+
df = new Deferred()
|
183
|
+
promise = df.promise()
|
184
|
+
|
185
|
+
df.reject({myObj: true})
|
186
|
+
|
187
|
+
wasRejected = false
|
188
|
+
promise.then (obj)->
|
189
|
+
expect('not to be called').toBe(true)
|
190
|
+
wasRejected = false
|
191
|
+
, (obj)->
|
192
|
+
expect(obj.myObj).toBe(true)
|
193
|
+
wasRejected = true
|
194
|
+
|
195
|
+
waitsFor ->
|
196
|
+
return wasRejected
|
197
|
+
, 'promise to be rejected', 100
|
198
|
+
|
199
|
+
runs ->
|
200
|
+
expect(wasRejected).toBe(true)
|
201
|
+
|
202
|
+
return
|
@@ -0,0 +1,23 @@
|
|
1
|
+
define 'spec/utilities/properties', ['utilities/properties'], (Properties) ->
|
2
|
+
describe 'Properties generator', ->
|
3
|
+
|
4
|
+
it 'should be able to add properties to a object', ->
|
5
|
+
obj = {}
|
6
|
+
Properties.add obj,
|
7
|
+
val1: {value:'test 1 value',static:true}
|
8
|
+
val2: {value: 'test 2 value'}
|
9
|
+
|
10
|
+
expect(obj.__auto__val1).toBe('test 1 value')
|
11
|
+
expect(obj.val1()).toBe('test 1 value')
|
12
|
+
expect(obj.__auto__val2).toBe('test 2 value')
|
13
|
+
expect(obj.val2()).toBe('test 2 value')
|
14
|
+
|
15
|
+
obj.val1('failed value')
|
16
|
+
expect(obj.val1()).toBe('test 1 value')
|
17
|
+
|
18
|
+
obj.val2('failed value 2')
|
19
|
+
expect(obj.val2()).toBe('failed value 2')
|
20
|
+
return
|
21
|
+
return
|
22
|
+
|
23
|
+
return
|
@@ -0,0 +1,40 @@
|
|
1
|
+
// Backbone.js 0.9.2
|
2
|
+
|
3
|
+
// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
|
4
|
+
// Backbone may be freely distributed under the MIT license.
|
5
|
+
// For all details and documentation:
|
6
|
+
// http://backbonejs.org
|
7
|
+
(function(){var k=this,y=k.Backbone,z=Array.prototype.splice,g;g="undefined"!==typeof exports?exports:k.Backbone={};g.VERSION="0.9.2";var f=k._;!f&&"undefined"!==typeof require&&(f=require("underscore"));g.$=k.jQuery||k.Zepto||k.ender;g.noConflict=function(){k.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var p=/\s+/,h=g.Events={on:function(a,b,c){var d,e;if(!b)return this;a=a.split(p);for(d=this._callbacks||(this._callbacks={});e=a.shift();)e=d[e]||(d[e]=[]),e.push(b,c);return this},
|
8
|
+
off:function(a,b,c){var d,e,m;if(!(e=this._callbacks))return this;if(!a&&!b&&!c)return delete this._callbacks,this;for(a=a?a.split(p):f.keys(e);d=a.shift();)if(!(m=e[d])||!b&&!c)delete e[d];else for(d=m.length-2;0<=d;d-=2)b&&m[d]!==b||c&&m[d+1]!==c||m.splice(d,2);return this},trigger:function(a){var b,c,d,e,f,g,j;if(!(c=this._callbacks))return this;j=[];a=a.split(p);e=1;for(f=arguments.length;e<f;e++)j[e-1]=arguments[e];for(;b=a.shift();){if(g=c.all)g=g.slice();if(d=c[b])d=d.slice();if(d){e=0;for(f=
|
9
|
+
d.length;e<f;e+=2)d[e].apply(d[e+1]||this,j)}if(g){b=[b].concat(j);e=0;for(f=g.length;e<f;e+=2)g[e].apply(g[e+1]||this,b)}}return this}};h.bind=h.on;h.unbind=h.off;var o=g.Model=function(a,b){var c;a||(a={});b&&b.collection&&(this.collection=b.collection);b&&b.parse&&(a=this.parse(a));if(c=l(this,"defaults"))a=f.extend({},c,a);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.changed={};this._silent={};this._pending={};this.set(a,{silent:!0});this.changed={};this._silent=
|
10
|
+
{};this._pending={};this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(o.prototype,h,{changed:null,_silent:null,_pending:null,idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},sync:function(){return g.sync.apply(this,arguments)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.get(a);return this._escapedAttributes[a]=f.escape(null==b?"":""+b)},
|
11
|
+
has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;d instanceof o&&(d=d.attributes);if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return!1;this.idAttribute in d&&(this.id=d[this.idAttribute]);var b=c.changes={},g=this.attributes,i=this._escapedAttributes,j=this._previousAttributes||{};for(e in d){a=d[e];if(!f.isEqual(g[e],a)||c.unset&&f.has(g,e))delete i[e],(c.silent?this._silent:b)[e]=!0;c.unset?
|
12
|
+
delete g[e]:g[e]=a;!f.isEqual(j[e],a)||f.has(g,e)!==f.has(j,e)?(this.changed[e]=a,c.silent||(this._pending[e]=!0)):(delete this.changed[e],delete this._pending[e])}c.silent||this.change(c);return this},unset:function(a,b){b=f.extend({},b,{unset:!0});return this.set(a,null,b)},clear:function(a){a=f.extend({},a,{unset:!0});return this.set(f.clone(this.attributes),a)},fetch:function(a){var a=a?f.clone(a):{},b=this,c=a.success;a.success=function(d,e,f){if(!b.set(b.parse(d,f),a))return!1;c&&c(b,d,a);b.trigger("sync",
|
13
|
+
b,d,a)};a.error=g.wrapError(a.error,b,a);return this.sync("read",this,a)},save:function(a,b,c){var d,e,m;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};if(c.wait){if(!this._validate(d,c))return!1;e=f.clone(this.attributes)}a=f.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c)||!d&&!this.isValid())return!1;var i=this,j=c.success;c.success=function(a,b,e){m=true;b=i.parse(a,e);c.wait&&(b=f.extend(d||{},b));if(!i.set(b,c))return false;j&&j(i,a,c);i.trigger("sync",i,a,c)};c.error=
|
14
|
+
g.wrapError(c.error,i,c);b=this.sync(this.isNew()?"create":"update",this,c);!m&&c.wait&&(this.clear(a),this.set(e,a));return b},destroy:function(a){var a=a?f.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};a.success=function(e){(a.wait||b.isNew())&&d();c&&c(b,e,a);b.isNew()||b.trigger("sync",b,e,a)};if(this.isNew())return a.success(),!1;a.error=g.wrapError(a.error,b,a);var e=this.sync("delete",this,a);a.wait||d();return e},url:function(){var a=l(this,"urlRoot")||
|
15
|
+
l(this.collection,"url")||s();return this.isNew()?a:a+("/"===a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){a||(a={});var b=this._changing;this._changing=!0;for(var c in this._silent)this._pending[c]=!0;var d=f.extend({},a.changes,this._silent);this._silent={};for(c in d)this.trigger("change:"+c,this,this.get(c),a);if(b)return this;for(;!f.isEmpty(this._pending);){this._pending=
|
16
|
+
{};this.trigger("change",this,a);for(c in this.changed)!this._pending[c]&&!this._silent[c]&&delete this.changed[c];this._previousAttributes=f.clone(this.attributes)}this._changing=!1;return this},hasChanged:function(a){return null==a?!f.isEmpty(this.changed):f.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?f.clone(this.changed):!1;var b,c=!1,d=this._previousAttributes,e;for(e in a)if(!f.isEqual(d[e],b=a[e]))(c||(c={}))[e]=b;return c},previous:function(a){return null==
|
17
|
+
a||!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},isValid:function(){return!this.validate||!this.validate(this.attributes)},_validate:function(a,b){if(b.silent||!this.validate)return!0;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error?b.error(this,c,b):this.trigger("error",this,c,b);return!1}});var q=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);void 0!==b.comparator&&
|
18
|
+
(this.comparator=b.comparator);this._reset();this.initialize.apply(this,arguments);a&&(b.parse&&(a=this.parse(a)),this.reset(a,{silent:!0,parse:b.parse}))};f.extend(q.prototype,h,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},sync:function(){return g.sync.apply(this,arguments)},add:function(a,b){var c,d,e,g,i,j={},k={},h=[];b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(d=a.length;c<d;c++){if(!(e=a[c]=this._prepareModel(a[c],b)))throw Error("Can't add an invalid model to a collection");
|
19
|
+
g=e.cid;i=e.id;j[g]||this._byCid[g]||null!=i&&(k[i]||this._byId[i])?h.push(c):j[g]=k[i]=e}for(c=h.length;c--;)h[c]=a.splice(h[c],1)[0];c=0;for(d=a.length;c<d;c++)(e=a[c]).on("all",this._onModelEvent,this),this._byCid[e.cid]=e,null!=e.id&&(this._byId[e.id]=e);this.length+=d;z.apply(this.models,[null!=b.at?b.at:this.models.length,0].concat(a));if(b.merge){c=0;for(d=h.length;c<d;c++)(e=this._byId[h[c].id])&&e.set(h[c],b)}this.comparator&&null==b.at&&this.sort({silent:!0});if(b.silent)return this;c=0;
|
20
|
+
for(d=this.models.length;c<d;c++)if(j[(e=this.models[c]).cid])b.index=c,e.trigger("add",e,this,b);return this},remove:function(a,b){var c,d,e,g;b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(d=a.length;c<d;c++)if(g=this.getByCid(a[c])||this.get(a[c]))delete this._byId[g.id],delete this._byCid[g.cid],e=this.indexOf(g),this.models.splice(e,1),this.length--,b.silent||(b.index=e,g.trigger("remove",g,this,b)),this._removeReference(g);return this},push:function(a,b){a=this._prepareModel(a,b);this.add(a,
|
21
|
+
b);return a},pop:function(a){var b=this.at(this.length-1);this.remove(b,a);return b},unshift:function(a,b){a=this._prepareModel(a,b);this.add(a,f.extend({at:0},b));return a},shift:function(a){var b=this.at(0);this.remove(b,a);return b},slice:function(a,b){return this.models.slice(a,b)},get:function(a){return null==a?void 0:this._byId[null!=a.id?a.id:a]},getByCid:function(a){return a&&this._byCid[a.cid||a]},at:function(a){return this.models[a]},where:function(a){return f.isEmpty(a)?[]:this.filter(function(b){for(var c in a)if(a[c]!==
|
22
|
+
b.get(c))return!1;return!0})},sort:function(a){a||(a={});if(!this.comparator)throw Error("Cannot sort a set without a comparator");var b=f.bind(this.comparator,this);1===this.comparator.length?this.models=this.sortBy(b):this.models.sort(b);a.silent||this.trigger("reset",this,a);return this},pluck:function(a){return f.map(this.models,function(b){return b.get(a)})},reset:function(a,b){a||(a=[]);b||(b={});for(var c=0,d=this.models.length;c<d;c++)this._removeReference(this.models[c]);this._reset();this.add(a,
|
23
|
+
f.extend({silent:!0},b));b.silent||this.trigger("reset",this,b);return this},fetch:function(a){a=a?f.clone(a):{};void 0===a.parse&&(a.parse=!0);var b=this,c=a.success;a.success=function(d,e,f){b[a.add?"add":"reset"](b.parse(d,f),a);c&&c(b,d,a);b.trigger("sync",b,d,a)};a.error=g.wrapError(a.error,b,a);return this.sync("read",this,a)},create:function(a,b){var c=this,b=b?f.clone(b):{},a=this._prepareModel(a,b);if(!a)return!1;b.wait||c.add(a,b);var d=b.success;b.success=function(a,b,f){f.wait&&c.add(a,
|
24
|
+
f);d&&d(a,b,f)};a.save(null,b);return a},parse:function(a){return a},clone:function(){return new this.constructor(this.models)},chain:function(){return f(this.models).chain()},_reset:function(){this.length=0;this.models=[];this._byId={};this._byCid={}},_prepareModel:function(a,b){if(a instanceof o)return a.collection||(a.collection=this),a;b||(b={});b.collection=this;var c=new this.model(a,b);return!c._validate(c.attributes,b)?!1:c},_removeReference:function(a){this===a.collection&&delete a.collection;
|
25
|
+
a.off("all",this._onModelEvent,this)},_onModelEvent:function(a,b,c,d){("add"===a||"remove"===a)&&c!==this||("destroy"===a&&this.remove(b,d),b&&a==="change:"+b.idAttribute&&(delete this._byId[b.previous(b.idAttribute)],null!=b.id&&(this._byId[b.id]=b)),this.trigger.apply(this,arguments))}});f.each("forEach each map reduce reduceRight find detect filter select reject every all some any include contains invoke max min sortBy sortedIndex toArray size first initial rest last without indexOf shuffle lastIndexOf isEmpty groupBy".split(" "),
|
26
|
+
function(a){q.prototype[a]=function(){return f[a].apply(f,[this.models].concat(f.toArray(arguments)))}});var t=g.Router=function(a){a||(a={});a.routes&&(this.routes=a.routes);this._bindRoutes();this.initialize.apply(this,arguments)},A=/:\w+/g,B=/\*\w+/g,C=/[-[\]{}()+?.,\\^$|#\s]/g;f.extend(t.prototype,h,{initialize:function(){},route:function(a,b,c){g.history||(g.history=new n);f.isRegExp(a)||(a=this._routeToRegExp(a));c||(c=this[b]);g.history.route(a,f.bind(function(d){d=this._extractParameters(a,
|
27
|
+
d);c&&c.apply(this,d);this.trigger.apply(this,["route:"+b].concat(d));g.history.trigger("route",this,b,d)},this));return this},navigate:function(a,b){g.history.navigate(a,b)},_bindRoutes:function(){if(this.routes){var a=[],b;for(b in this.routes)a.unshift([b,this.routes[b]]);b=0;for(var c=a.length;b<c;b++)this.route(a[b][0],a[b][1],this[a[b][1]])}},_routeToRegExp:function(a){a=a.replace(C,"\\$&").replace(A,"([^/]+)").replace(B,"(.*?)");return RegExp("^"+a+"$")},_extractParameters:function(a,b){return a.exec(b).slice(1)}});
|
28
|
+
var n=g.History=function(a){this.handlers=[];f.bindAll(this,"checkUrl");this.location=a&&a.location||k.location;this.history=a&&a.history||k.history},r=/^[#\/]/,D=/msie [\w.]+/,u=/\/$/;n.started=!1;f.extend(n.prototype,h,{interval:50,getHash:function(a){return(a=(a||this).location.href.match(/#(.*)$/))?a[1]:""},getFragment:function(a,b){if(null==a)if(this._hasPushState||!this._wantsHashChange||b){var a=this.location.pathname,c=this.options.root.replace(u,"");a.indexOf(c)||(a=a.substr(c.length))}else a=
|
29
|
+
this.getHash();return decodeURIComponent(a.replace(r,""))},start:function(a){if(n.started)throw Error("Backbone.history has already been started");n.started=!0;this.options=f.extend({},{root:"/"},this.options,a);this._wantsHashChange=!1!==this.options.hashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!(!this.options.pushState||!this.history||!this.history.pushState);var a=this.getFragment(),b=document.documentMode,b=D.exec(navigator.userAgent.toLowerCase())&&(!b||7>=b);u.test(this.options.root)||
|
30
|
+
(this.options.root+="/");b&&this._wantsHashChange&&(this.iframe=g.$('<iframe src="javascript:0" tabindex="-1" />').hide().appendTo("body")[0].contentWindow,this.navigate(a));this._hasPushState?g.$(window).bind("popstate",this.checkUrl):this._wantsHashChange&&"onhashchange"in window&&!b?g.$(window).bind("hashchange",this.checkUrl):this._wantsHashChange&&(this._checkUrlInterval=setInterval(this.checkUrl,this.interval));this.fragment=a;a=this.location;b=a.pathname.replace(/[^/]$/,"$&/")===this.options.root&&
|
31
|
+
!a.search;if(this._wantsHashChange&&this._wantsPushState&&!this._hasPushState&&!b)return this.fragment=this.getFragment(null,!0),this.location.replace(this.options.root+this.location.search+"#"+this.fragment),!0;this._wantsPushState&&(this._hasPushState&&b&&a.hash)&&(this.fragment=this.getHash().replace(r,""),this.history.replaceState({},document.title,a.protocol+"//"+a.host+this.options.root+this.fragment));if(!this.options.silent)return this.loadUrl()},stop:function(){g.$(window).unbind("popstate",
|
32
|
+
this.checkUrl).unbind("hashchange",this.checkUrl);clearInterval(this._checkUrlInterval);n.started=!1},route:function(a,b){this.handlers.unshift({route:a,callback:b})},checkUrl:function(){var a=this.getFragment();a===this.fragment&&this.iframe&&(a=this.getFragment(this.getHash(this.iframe)));if(a===this.fragment)return!1;this.iframe&&this.navigate(a);this.loadUrl()||this.loadUrl(this.getHash())},loadUrl:function(a){var b=this.fragment=this.getFragment(a);return f.any(this.handlers,function(a){if(a.route.test(b))return a.callback(b),
|
33
|
+
!0})},navigate:function(a,b){if(!n.started)return!1;if(!b||!0===b)b={trigger:b};var c=(a||"").replace(r,"");if(this.fragment!==c){this.fragment=c;var d=(0!==c.indexOf(this.options.root)?this.options.root:"")+c;if(this._hasPushState)this.history[b.replace?"replaceState":"pushState"]({},document.title,d);else if(this._wantsHashChange)this._updateHash(this.location,c,b.replace),this.iframe&&c!==this.getFragment(this.getHash(this.iframe))&&(b.replace||this.iframe.document.open().close(),this._updateHash(this.iframe.location,
|
34
|
+
c,b.replace));else return this.location.assign(d);b.trigger&&this.loadUrl(a)}},_updateHash:function(a,b,c){c?a.replace(a.href.replace(/(javascript:|#).*$/,"")+"#"+b):a.hash=b}});var v=g.View=function(a){this.cid=f.uniqueId("view");this._configure(a||{});this._ensureElement();this.initialize.apply(this,arguments);this.delegateEvents()},E=/^(\S+)\s*(.*)$/,w="model collection el id attributes className tagName".split(" ");f.extend(v.prototype,h,{tagName:"div",$:function(a){return this.$el.find(a)},initialize:function(){},
|
35
|
+
render:function(){return this},dispose:function(){this.undelegateEvents();this.model&&this.model.off(null,null,this);this.collection&&this.collection.off(null,null,this);return this},remove:function(){this.dispose();this.$el.remove();return this},make:function(a,b,c){a=document.createElement(a);b&&g.$(a).attr(b);null!=c&&g.$(a).html(c);return a},setElement:function(a,b){this.$el&&this.undelegateEvents();this.$el=a instanceof g.$?a:g.$(a);this.el=this.$el[0];!1!==b&&this.delegateEvents();return this},
|
36
|
+
delegateEvents:function(a){if(a||(a=l(this,"events"))){this.undelegateEvents();for(var b in a){var c=a[b];f.isFunction(c)||(c=this[a[b]]);if(!c)throw Error('Method "'+a[b]+'" does not exist');var d=b.match(E),e=d[1],d=d[2],c=f.bind(c,this),e=e+(".delegateEvents"+this.cid);""===d?this.$el.bind(e,c):this.$el.delegate(d,e,c)}}},undelegateEvents:function(){this.$el.unbind(".delegateEvents"+this.cid)},_configure:function(a){this.options&&(a=f.extend({},this.options,a));for(var b=0,c=w.length;b<c;b++){var d=
|
37
|
+
w[b];a[d]&&(this[d]=a[d])}this.options=a},_ensureElement:function(){if(this.el)this.setElement(this.el,!1);else{var a=f.extend({},l(this,"attributes"));this.id&&(a.id=l(this,"id"));this.className&&(a["class"]=l(this,"className"));this.setElement(this.make(l(this,"tagName"),a),!1)}}});o.extend=q.extend=t.extend=v.extend=function(a,b){var c=this,d;d=a&&a.hasOwnProperty("constructor")?a.constructor:function(){c.apply(this,arguments)};f.extend(d,c);x.prototype=c.prototype;d.prototype=new x;a&&f.extend(d.prototype,
|
38
|
+
a);b&&f.extend(d,b);d.prototype.constructor=d;d.__super__=c.prototype;return d};var F={create:"POST",update:"PUT","delete":"DELETE",read:"GET"};g.sync=function(a,b,c){var d=F[a];c||(c={});var e={type:d,dataType:"json"};c.url||(e.url=l(b,"url")||s());if(!c.data&&b&&("create"===a||"update"===a))e.contentType="application/json",e.data=JSON.stringify(b);g.emulateJSON&&(e.contentType="application/x-www-form-urlencoded",e.data=e.data?{model:e.data}:{});if(g.emulateHTTP&&("PUT"===d||"DELETE"===d))g.emulateJSON&&
|
39
|
+
(e.data._method=d),e.type="POST",e.beforeSend=function(a){a.setRequestHeader("X-HTTP-Method-Override",d)};"GET"!==e.type&&!g.emulateJSON&&(e.processData=!1);return g.ajax(f.extend(e,c))};g.ajax=function(){return g.$.ajax.apply(g.$,arguments)};g.wrapError=function(a,b,c){return function(d,e){e=d===b?e:d;a?a(b,e,c):b.trigger("error",b,e,c)}};var x=function(){},l=function(a,b){return!a||!a[b]?null:f.isFunction(a[b])?a[b]():a[b]},s=function(){throw Error('A "url" property or function must be specified');
|
40
|
+
}}).call(this);
|
data/assets/tasks/www.rake
CHANGED
@@ -11,7 +11,7 @@ sprockets = (Sprockets::Environment.new(ROOT) { |env| env.logger = Logger.new(ST
|
|
11
11
|
sprockets.append_path WWW_SRC_VENDOR_PATH.join('css').to_s
|
12
12
|
sprockets.append_path WWW_SRC_APP_PATH.join('sass').to_s
|
13
13
|
sprockets.append_path WWW_SRC_VENDOR_PATH.join('js').to_s
|
14
|
-
sprockets.append_path WWW_SRC_APP_PATH.join('
|
14
|
+
sprockets.append_path WWW_SRC_APP_PATH.join('scripts').to_s
|
15
15
|
sprockets.append_path WWW_SRC_APP_PATH.join('templates').to_s
|
16
16
|
|
17
17
|
# Note: Requires JVM for YUI
|
@@ -22,34 +22,8 @@ sprockets.js_compressor = Uglifier.new(mangle: true)
|
|
22
22
|
sprockets.register_mime_type('text/gotmpl', '.gotmpl')
|
23
23
|
sprockets.register_processor('text/gotmpl', Sprockets::DirectiveProcessor)
|
24
24
|
|
25
|
-
|
26
25
|
Dir.glob("#{WWW_SRC_APP_PATH}/erb_helpers/**/*.rb").sort.each { |helper| load helper }
|
27
26
|
|
28
|
-
|
29
|
-
desc 'Iterates over the input directory building a list of coffee files to compile'
|
30
|
-
def coffee(inDir, outDir)
|
31
|
-
Dir.glob("#{inDir}/**/*.coffee").each do |file|
|
32
|
-
outFile = file.partition(inDir)[2]
|
33
|
-
next if (outFile.empty?)
|
34
|
-
outFile.sub!(/coffee$/, 'js')
|
35
|
-
coffee_compile(file, outDir+outFile)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
desc 'Compiles the coffee script file and writes it to the out'
|
40
|
-
def coffee_compile(inFile, outFile)
|
41
|
-
begin
|
42
|
-
File.delete(outFile) if (FileTest::file?(outFile))
|
43
|
-
FileUtils::mkdir_p(File.dirname(outFile)) if (!FileTest::directory?(File.dirname(outFile)))
|
44
|
-
|
45
|
-
f = File.new(outFile, "w")
|
46
|
-
f.write(CoffeeScript.compile(File.read(inFile)))
|
47
|
-
f.close()
|
48
|
-
rescue
|
49
|
-
puts "Failed to compile #{inFile} to #{outFile}"
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
27
|
namespace :app do
|
54
28
|
namespace :www do
|
55
29
|
task :init do
|
@@ -73,8 +47,35 @@ namespace :app do
|
|
73
47
|
end
|
74
48
|
end
|
75
49
|
|
76
|
-
task :
|
77
|
-
|
50
|
+
task :spec do
|
51
|
+
out_dir = WWW_SPEC_PATH
|
52
|
+
in_dir = WWW_SRC_SPEC_PATH
|
53
|
+
|
54
|
+
Dir.glob(in_dir.join('**', '*')).each do |file|
|
55
|
+
out_file = File.join(out_dir, file.partition(in_dir.to_s)[2])
|
56
|
+
next if (out_file.empty?)
|
57
|
+
|
58
|
+
if FileTest::directory?(file)
|
59
|
+
next
|
60
|
+
end
|
61
|
+
|
62
|
+
FileUtils::mkdir_p(File.dirname(out_file)) if (!FileTest::directory?(File.dirname(out_file)))
|
63
|
+
|
64
|
+
begin
|
65
|
+
if file.match('.coffee$')
|
66
|
+
out_file.sub!(/coffee$/, 'js')
|
67
|
+
File.delete(out_file) if (FileTest::file?(out_file))
|
68
|
+
|
69
|
+
f = File.new(out_file, "w")
|
70
|
+
f.write(CoffeeScript.compile(File.read(file)))
|
71
|
+
f.close()
|
72
|
+
else
|
73
|
+
FileUtils::cp file, out_file
|
74
|
+
end
|
75
|
+
rescue Exception => e
|
76
|
+
$stderr.puts "Failed to compile and copy spec #{file}, because #{e}"
|
77
|
+
end
|
78
|
+
end
|
78
79
|
end
|
79
80
|
|
80
81
|
task :images do
|
@@ -131,7 +132,7 @@ namespace :app do
|
|
131
132
|
end
|
132
133
|
end
|
133
134
|
rescue Exception => e
|
134
|
-
$stderr.puts "Failed to compile assets,
|
135
|
+
$stderr.puts "Failed to compile assets, because #{e}"
|
135
136
|
end
|
136
137
|
end
|
137
138
|
|
@@ -146,19 +147,19 @@ namespace :app do
|
|
146
147
|
|
147
148
|
assets.write_to(outfile)
|
148
149
|
rescue Exception => e
|
149
|
-
$stderr.puts "Failed to compile template,
|
150
|
+
$stderr.puts "Failed to compile template, because #{e}"
|
150
151
|
end
|
151
152
|
end
|
152
153
|
|
153
154
|
desc 'Builds the existing source'
|
154
|
-
task :build => [:init,:compile,:compile_templates,:
|
155
|
+
task :build => [:init,:compile,:compile_templates,:spec,:images,:partials]
|
155
156
|
|
156
157
|
desc 'Cleans the build path'
|
157
158
|
task :clean do
|
158
159
|
paths = []
|
159
160
|
paths << ASSETS_PATH
|
160
161
|
paths << TMPL_BUILD_PATH
|
161
|
-
paths <<
|
162
|
+
paths << WWW_SPEC_PATH
|
162
163
|
|
163
164
|
paths.each do |path|
|
164
165
|
begin
|