gokart 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (29) hide show
  1. data/assets/Guardfile +7 -3
  2. data/assets/config.rb +1 -1
  3. data/assets/src/www/app/scripts/application.js.coffee +5 -0
  4. data/assets/src/www/app/scripts/main.js.coffee +9 -0
  5. data/assets/src/www/app/{coffee/libs → scripts/utilities}/deferred.js.coffee +4 -10
  6. data/assets/src/www/app/{coffee/libs → scripts/utilities}/logger.js.coffee +7 -4
  7. data/assets/src/www/app/{coffee/helpers → scripts/utilities}/properties.js.coffee +5 -3
  8. data/assets/src/www/app/scripts/utilities/require.js +69 -0
  9. data/assets/src/www/spec/all-spec.js +11 -0
  10. data/assets/src/www/spec/helpers/mocks.coffee +8 -0
  11. data/assets/{spec/javascripts → src/www/spec}/support/jasmine.yml +2 -4
  12. data/assets/{spec/javascripts → src/www/spec}/support/jasmine_config.rb +0 -0
  13. data/assets/{spec/javascripts → src/www/spec}/support/jasmine_runner.rb +0 -0
  14. data/assets/src/www/spec/utilities/deferred-spec.coffee +202 -0
  15. data/assets/src/www/spec/utilities/properties-spec.coffee +23 -0
  16. data/assets/src/www/spec/utilities/test-spec.js +7 -0
  17. data/assets/src/www/vendor/js/backbone-min.js +40 -0
  18. data/assets/tasks/www.rake +34 -33
  19. data/lib/gokart/base.rb +6 -3
  20. data/lib/gokart/environment.rb +1 -19
  21. data/lib/gokart/version.rb +1 -1
  22. metadata +47 -45
  23. data/assets/src/www/app/coffee/application.js.coffee +0 -6
  24. data/assets/src/www/app/coffee/libs/mod_loader.js.coffee +0 -44
  25. data/assets/src/www/app/coffee/main.js.coffee +0 -10
  26. data/assets/src/www/spec/coffee/deferred-spec.coffee +0 -202
  27. data/assets/src/www/spec/coffee/mocks.coffee +0 -137
  28. data/assets/src/www/spec/coffee/mod_loader-spec.coffee +0 -45
  29. 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/coffee', :output => 'spec/javascripts', :hide_success => true
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/coffee/.+$})
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/javascripts/.+$})
39
+ watch(%r{bin/assets/www-debug/js/.+$})
36
40
  watch(%r{spec/javascripts/.+$})
37
41
  end
data/assets/config.rb CHANGED
@@ -3,7 +3,7 @@ require 'bundler'
3
3
 
4
4
  Bundler.require
5
5
 
6
- if !defined? ROOT
6
+ unless defined? ROOT
7
7
  ROOT = Pathname(File.dirname(__FILE__))
8
8
 
9
9
  ASSET_BUNDLES = %w( application.css application.js )
@@ -0,0 +1,5 @@
1
+ #= require utilities/require
2
+ #= require utilities/deferred
3
+ #= require utilities/logger
4
+ #= require utilities/properties
5
+ #= require main
@@ -0,0 +1,9 @@
1
+
2
+ # Application main entry point
3
+ define 'app', ['utilities/logger'], (Logger) ->
4
+
5
+ # This function runs once the page is loaded
6
+ onDocLoaded = ->
7
+ return
8
+
9
+ window.addEventListener("load", onDocLoaded, false)
@@ -1,6 +1,4 @@
1
- modLoader.define 'libs/deferred', (require, exports)=>
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(context, data)
12
+ done.apply(null, data)
15
13
  return
16
14
 
17
15
  _doFail: (data)->
18
16
  for fail in @_fails
19
- fail.apply(context, data)
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
- modLoader.define 'libs/logger', (require,exports)->
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
- exports.getInstance = (name) =>
33
+ getInstance = (name) =>
34
34
  _initLogger() if !@appLoggerInstance
35
35
  return @appLoggerInstance
36
36
 
37
- exports.reset = =>
37
+ reset = =>
38
38
  delete @appLoggerInstance
39
39
 
40
- return
40
+ return {
41
+ getInstance: getInstance
42
+ reset: reset
43
+ }
@@ -1,4 +1,4 @@
1
- modLoader.define 'helpers/properties', (require,exports)->
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
- exports.add = (cont, props)->
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);
@@ -0,0 +1,11 @@
1
+ define('spec/all', [
2
+ 'spec/mocks',
3
+ 'spec/utilities/test',
4
+ 'spec/utilities/deferred',
5
+ 'spec/utilities/properties'
6
+ ], function(){});
7
+
8
+ window.addEventListener('load', function(){
9
+ require('spec/all');
10
+ jasmine.getEnv().execute()
11
+ }, false);
@@ -0,0 +1,8 @@
1
+ define 'spec/mocks', [], ->
2
+
3
+ Mocks = {}
4
+
5
+ Mocks.ajax = jasmine.createSpy('AJAX Stub').andCallFake () ->
6
+ return
7
+
8
+ return Mocks
@@ -11,9 +11,8 @@
11
11
  # - dist/**/*.js
12
12
  #
13
13
  src_files:
14
- - js/libs/mod_loader.js
15
- - js/libs/deferred.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
  #
@@ -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,7 @@
1
+ define('spec/utilities/test', [], function() {
2
+ describe('Bha lbah lbah', function() {
3
+ it('should blah', function(){
4
+ expect(true).toBe(true);
5
+ });
6
+ });
7
+ });
@@ -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);
@@ -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('coffee').to_s
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 :spec_coffee do
77
- coffee "#{WWW_SRC_SPEC_PATH}/coffee", WWW_SPEC_PATH.to_s
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, becasue #{e}"
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, becasue #{e}"
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,:spec_coffee,:images,:partials]
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 << Dir.glob("#{WWW_SPEC_PATH}/*.js")
162
+ paths << WWW_SPEC_PATH
162
163
 
163
164
  paths.each do |path|
164
165
  begin