spine-rails 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/build/update.sh +1 -1
- data/lib/generators/spine/model/model_generator.rb +2 -2
- data/lib/generators/spine/new/new_generator.rb +3 -3
- data/lib/spine/generators.rb +2 -2
- data/lib/spine/rails/version.rb +2 -2
- data/vendor/assets/javascripts/spine.coffee +87 -88
- data/vendor/assets/javascripts/spine/ajax.coffee +58 -40
- data/vendor/assets/javascripts/spine/list.coffee +0 -0
- data/vendor/assets/javascripts/spine/local.coffee +3 -2
- data/vendor/assets/javascripts/spine/manager.coffee +5 -6
- data/vendor/assets/javascripts/spine/relation.coffee +0 -0
- data/vendor/assets/javascripts/spine/route.coffee +12 -1
- metadata +13 -21
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: bc6e555ec210a066a3fe6e5b10517924a9f1c6dd
|
4
|
+
data.tar.gz: 2cd2df11d007b2374837025820afc2b965a144b4
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: a1ae34db175522354f034139ea94cf43e81636a5c6c08de7ad423ab2b125c6f9d8a8ce66aff574a94d7fc88201c8e3a60c342836024bd07c0d8df44c1eecfa82
|
7
|
+
data.tar.gz: 7d145f0bce2a4416338831155f47f0c8cddf6ba6ecaf9402d64d62911de601c6c3077d754925c15a860ddf51f159ecc49d126cda847f4bff7958a5090fef490a
|
data/build/update.sh
CHANGED
@@ -7,11 +7,11 @@ module Spine
|
|
7
7
|
source_root File.expand_path("../templates", __FILE__)
|
8
8
|
desc "Generate a Spine model with configured fields"
|
9
9
|
|
10
|
-
argument :fields, desc
|
10
|
+
argument :fields, :desc => 'List of model attributes', :type => :array, :banner => 'field1 field2'
|
11
11
|
|
12
12
|
def create_model
|
13
13
|
template "model.coffee.erb", "app/assets/javascripts/#{app_name}/models/#{file_name}.js.coffee"
|
14
14
|
end
|
15
15
|
end
|
16
16
|
end
|
17
|
-
end
|
17
|
+
end
|
@@ -7,7 +7,7 @@ module Spine
|
|
7
7
|
|
8
8
|
desc "This generator installs Spine #{Spine::Rails::SPINE_VERSION} as part of assets pipeline"
|
9
9
|
|
10
|
-
class_option :app, type
|
10
|
+
class_option :app, :type => :string, :default => "app", :desc => "app name"
|
11
11
|
|
12
12
|
def app_name
|
13
13
|
options[:app]
|
@@ -37,7 +37,7 @@ module Spine
|
|
37
37
|
content = File.read(source)
|
38
38
|
|
39
39
|
if content.include?("//= require_tree .")
|
40
|
-
inject_into_file source, before
|
40
|
+
inject_into_file source, :before => "//= require_tree ." do
|
41
41
|
"//= require #{app_name}\n"
|
42
42
|
end
|
43
43
|
else
|
@@ -46,4 +46,4 @@ module Spine
|
|
46
46
|
end
|
47
47
|
end
|
48
48
|
end
|
49
|
-
end
|
49
|
+
end
|
data/lib/spine/generators.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module Spine
|
2
2
|
module Generators
|
3
3
|
class Base < ::Rails::Generators::NamedBase
|
4
|
-
class_option :app, type
|
4
|
+
class_option :app, :type => :string, :default => "app", :desc => "app name"
|
5
5
|
|
6
6
|
protected
|
7
7
|
|
@@ -18,4 +18,4 @@ module Spine
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
21
|
-
end
|
21
|
+
end
|
data/lib/spine/rails/version.rb
CHANGED
@@ -24,36 +24,46 @@ Events =
|
|
24
24
|
listenTo: (obj, ev, callback) ->
|
25
25
|
obj.bind(ev, callback)
|
26
26
|
@listeningTo or= []
|
27
|
-
@listeningTo.push obj
|
27
|
+
@listeningTo.push {obj, ev, callback}
|
28
28
|
this
|
29
29
|
|
30
30
|
listenToOnce: (obj, ev, callback) ->
|
31
31
|
listeningToOnce = @listeningToOnce or = []
|
32
|
-
|
33
|
-
|
34
|
-
|
32
|
+
obj.bind ev, handler = ->
|
33
|
+
idx = -1
|
34
|
+
for lt, i in listeningToOnce when lt.obj is obj
|
35
|
+
idx = i if lt.ev is ev and lt.callback is callback
|
36
|
+
obj.unbind(ev, handler)
|
35
37
|
listeningToOnce.splice(idx, 1) unless idx is -1
|
36
38
|
callback.apply(this, arguments)
|
39
|
+
listeningToOnce.push {obj, ev, callback, handler}
|
37
40
|
this
|
38
41
|
|
39
|
-
stopListening: (obj,
|
42
|
+
stopListening: (obj, events, callback) ->
|
40
43
|
if arguments.length is 0
|
41
|
-
retain = []
|
42
44
|
for listeningTo in [@listeningTo, @listeningToOnce]
|
43
45
|
continue unless listeningTo
|
44
|
-
for
|
45
|
-
obj.unbind()
|
46
|
-
retain.push(obj)
|
46
|
+
for lt in listeningTo
|
47
|
+
lt.obj.unbind(lt.ev, lt.handler or lt.callback)
|
47
48
|
@listeningTo = undefined
|
48
49
|
@listeningToOnce = undefined
|
49
50
|
|
50
51
|
else if obj
|
51
|
-
obj.unbind(ev, callback) if ev
|
52
|
-
obj.unbind() unless ev
|
53
52
|
for listeningTo in [@listeningTo, @listeningToOnce]
|
54
53
|
continue unless listeningTo
|
55
|
-
|
56
|
-
|
54
|
+
events = if events then events.split(' ') else [undefined]
|
55
|
+
for ev in events
|
56
|
+
for idx in [listeningTo.length-1..0]
|
57
|
+
lt = listeningTo[idx]
|
58
|
+
if (not ev) or (ev is lt.ev)
|
59
|
+
lt.obj.unbind(lt.ev, lt.handler or lt.callback)
|
60
|
+
listeningTo.splice(idx, 1) unless idx is -1
|
61
|
+
else if ev
|
62
|
+
evts = lt.ev.split(' ')
|
63
|
+
if ~(i = evts.indexOf(ev))
|
64
|
+
evts.splice(i, 1)
|
65
|
+
lt.ev = $.trim(evts.join(' '))
|
66
|
+
lt.obj.unbind(ev, lt.handler or lt.callback)
|
57
67
|
|
58
68
|
unbind: (ev, callback) ->
|
59
69
|
if arguments.length is 0
|
@@ -117,10 +127,9 @@ class Module
|
|
117
127
|
class Model extends Module
|
118
128
|
@extend Events
|
119
129
|
|
120
|
-
@records: []
|
121
|
-
@irecords: {}
|
122
|
-
@
|
123
|
-
@attributes: []
|
130
|
+
@records : []
|
131
|
+
@irecords : {}
|
132
|
+
@attributes : []
|
124
133
|
|
125
134
|
@configure: (name, attributes...) ->
|
126
135
|
@className = name
|
@@ -139,28 +148,27 @@ class Model extends Module
|
|
139
148
|
return record
|
140
149
|
|
141
150
|
@exists: (id) ->
|
142
|
-
|
151
|
+
@irecords[id]?.clone()
|
152
|
+
|
153
|
+
@addRecord: (record) ->
|
154
|
+
if record.id and @irecords[record.id]
|
155
|
+
@irecords[record.id].remove()
|
156
|
+
|
157
|
+
record.id or= record.cid
|
158
|
+
@records.push(record)
|
159
|
+
@irecords[record.id] = record
|
160
|
+
@irecords[record.cid] = record
|
143
161
|
|
144
162
|
@refresh: (values, options = {}) ->
|
145
|
-
if options.clear
|
146
|
-
@deleteAll()
|
163
|
+
@deleteAll() if options.clear
|
147
164
|
|
148
165
|
records = @fromJSON(values)
|
149
166
|
records = [records] unless isArray(records)
|
150
|
-
|
151
|
-
for record in records
|
152
|
-
if record.id and @irecords[record.id]
|
153
|
-
@records[@records.indexOf(@irecords[record.id])] = record
|
154
|
-
else
|
155
|
-
record.id or= record.cid
|
156
|
-
@records.push(record)
|
157
|
-
@irecords[record.id] = record
|
158
|
-
@crecords[record.cid] = record
|
159
|
-
|
167
|
+
@addRecord(record) for record in records
|
160
168
|
@sort()
|
161
169
|
|
162
170
|
result = @cloneArray(records)
|
163
|
-
@trigger('refresh',
|
171
|
+
@trigger('refresh', result, options)
|
164
172
|
result
|
165
173
|
|
166
174
|
@select: (callback) ->
|
@@ -194,7 +202,6 @@ class Model extends Module
|
|
194
202
|
@deleteAll: ->
|
195
203
|
@records = []
|
196
204
|
@irecords = {}
|
197
|
-
@crecords = {}
|
198
205
|
|
199
206
|
@destroyAll: (options) ->
|
200
207
|
record.destroy(options) for record in @records
|
@@ -239,7 +246,7 @@ class Model extends Module
|
|
239
246
|
@sort: ->
|
240
247
|
if @comparator
|
241
248
|
@records.sort @comparator
|
242
|
-
|
249
|
+
this
|
243
250
|
|
244
251
|
# Private
|
245
252
|
|
@@ -258,7 +265,7 @@ class Model extends Module
|
|
258
265
|
constructor: (atts) ->
|
259
266
|
super
|
260
267
|
@load atts if atts
|
261
|
-
@cid = @constructor.uid('c-')
|
268
|
+
@cid = atts?.cid or @constructor.uid('c-')
|
262
269
|
|
263
270
|
isNew: ->
|
264
271
|
not @exists()
|
@@ -320,27 +327,29 @@ class Model extends Module
|
|
320
327
|
@save(options)
|
321
328
|
|
322
329
|
changeID: (id) ->
|
330
|
+
return if id is @id
|
323
331
|
records = @constructor.irecords
|
324
332
|
records[id] = records[@id]
|
325
333
|
delete records[@id]
|
326
334
|
@id = id
|
327
335
|
@save()
|
328
336
|
|
329
|
-
|
330
|
-
@trigger('beforeDestroy', options)
|
331
|
-
|
337
|
+
remove: ->
|
332
338
|
# Remove record from model
|
333
339
|
records = @constructor.records.slice(0)
|
334
340
|
for record, i in records when @eql(record)
|
335
341
|
records.splice(i, 1)
|
336
342
|
break
|
337
343
|
@constructor.records = records
|
338
|
-
|
339
344
|
# Remove the ID and CID
|
340
345
|
delete @constructor.irecords[@id]
|
341
|
-
delete @constructor.
|
346
|
+
delete @constructor.irecords[@cid]
|
342
347
|
|
348
|
+
destroy: (options = {}) ->
|
349
|
+
@trigger('beforeDestroy', options)
|
350
|
+
@remove()
|
343
351
|
@destroyed = true
|
352
|
+
# handle events
|
344
353
|
@trigger('destroy', options)
|
345
354
|
@trigger('change', 'destroy', options)
|
346
355
|
if @listeningTo
|
@@ -348,13 +357,13 @@ class Model extends Module
|
|
348
357
|
@unbind()
|
349
358
|
this
|
350
359
|
|
351
|
-
dup: (newRecord) ->
|
352
|
-
|
353
|
-
if newRecord
|
354
|
-
|
360
|
+
dup: (newRecord = true) ->
|
361
|
+
atts = @attributes()
|
362
|
+
if newRecord
|
363
|
+
delete atts.id
|
355
364
|
else
|
356
|
-
|
357
|
-
|
365
|
+
atts.cid = @cid
|
366
|
+
new @constructor(atts)
|
358
367
|
|
359
368
|
clone: ->
|
360
369
|
createObject(this)
|
@@ -365,6 +374,13 @@ class Model extends Module
|
|
365
374
|
@load(original.attributes())
|
366
375
|
original
|
367
376
|
|
377
|
+
refresh: (data) ->
|
378
|
+
# go to the source and load attributes
|
379
|
+
root = @constructor.irecords[@id]
|
380
|
+
root.load(data)
|
381
|
+
@trigger('refresh')
|
382
|
+
@
|
383
|
+
|
368
384
|
toJSON: ->
|
369
385
|
@attributes()
|
370
386
|
|
@@ -373,8 +389,18 @@ class Model extends Module
|
|
373
389
|
|
374
390
|
fromForm: (form) ->
|
375
391
|
result = {}
|
392
|
+
|
393
|
+
for checkbox in $(form).find('[type=checkbox]:not([value])')
|
394
|
+
result[checkbox.name] = $(checkbox).prop('checked')
|
395
|
+
|
396
|
+
for checkbox in $(form).find('[type=checkbox][name$="[]"]')
|
397
|
+
name = checkbox.name.replace(/\[\]$/, '')
|
398
|
+
result[name] or= []
|
399
|
+
result[name].push checkbox.value if $(checkbox).prop('checked')
|
400
|
+
|
376
401
|
for key in $(form).serializeArray()
|
377
|
-
result[key.name] = key.value
|
402
|
+
result[key.name] or= key.value
|
403
|
+
|
378
404
|
@load(result)
|
379
405
|
|
380
406
|
exists: ->
|
@@ -397,13 +423,10 @@ class Model extends Module
|
|
397
423
|
|
398
424
|
create: (options) ->
|
399
425
|
@trigger('beforeCreate', options)
|
400
|
-
@id
|
401
|
-
|
402
|
-
record = @dup(false)
|
403
|
-
@constructor.records.push(record)
|
404
|
-
@constructor.irecords[@id] = record
|
405
|
-
@constructor.crecords[@cid] = record
|
426
|
+
@id or= @cid
|
406
427
|
|
428
|
+
record = @dup(false)
|
429
|
+
@constructor.addRecord(record)
|
407
430
|
@constructor.sort()
|
408
431
|
|
409
432
|
clone = record.clone()
|
@@ -435,39 +458,9 @@ class Model extends Module
|
|
435
458
|
args.splice(1, 0, this)
|
436
459
|
@constructor.trigger(args...)
|
437
460
|
|
438
|
-
listenTo:
|
439
|
-
|
440
|
-
|
441
|
-
@listeningTo.push(obj)
|
442
|
-
|
443
|
-
listenToOnce: (obj, events, callback) ->
|
444
|
-
listeningToOnce = @listeningToOnce or= []
|
445
|
-
listeningToOnce.push obj
|
446
|
-
obj.bind events, handler = =>
|
447
|
-
idx = listeningToOnce.indexOf(obj)
|
448
|
-
listeningToOnce.splice(idx, 1) unless idx is -1
|
449
|
-
obj.unbind(events, handler)
|
450
|
-
callback.apply(obj, arguments)
|
451
|
-
|
452
|
-
stopListening: (obj, events, callback) ->
|
453
|
-
if arguments.length is 0
|
454
|
-
retain = []
|
455
|
-
for listeningTo in [@listeningTo, @listeningToOnce]
|
456
|
-
continue unless listeningTo
|
457
|
-
for obj in @listeningTo when not (obj in retain)
|
458
|
-
obj.unbind()
|
459
|
-
retain.push(obj)
|
460
|
-
@listeningTo = undefined
|
461
|
-
@listeningToOnce = undefined
|
462
|
-
return
|
463
|
-
|
464
|
-
if obj
|
465
|
-
obj.unbind() unless events
|
466
|
-
obj.unbind(events, callback) if events
|
467
|
-
for listeningTo in [@listeningTo, @listeningToOnce]
|
468
|
-
continue unless listeningTo
|
469
|
-
idx = listeningTo.indexOf(obj)
|
470
|
-
listeningTo.splice(idx, 1) unless idx is -1
|
461
|
+
listenTo: -> Events.listenTo.apply @, arguments
|
462
|
+
listenToOnce: -> Events.listenToOnce.apply @, arguments
|
463
|
+
stopListening: -> Events.stopListening.apply @, arguments
|
471
464
|
|
472
465
|
unbind: (events, callback) ->
|
473
466
|
if arguments.length is 0
|
@@ -515,6 +508,7 @@ class Controller extends Module
|
|
515
508
|
|
516
509
|
release: =>
|
517
510
|
@trigger 'release', this
|
511
|
+
# no need to unDelegateEvents since remove will end up handling that
|
518
512
|
@el.remove()
|
519
513
|
@unbind()
|
520
514
|
@stopListening()
|
@@ -544,7 +538,7 @@ class Controller extends Module
|
|
544
538
|
if selector is ''
|
545
539
|
@el.bind(eventName, method)
|
546
540
|
else
|
547
|
-
@el.
|
541
|
+
@el.on(eventName, selector, method)
|
548
542
|
|
549
543
|
refreshElements: ->
|
550
544
|
for key, value of @elements
|
@@ -553,6 +547,8 @@ class Controller extends Module
|
|
553
547
|
delay: (func, timeout) ->
|
554
548
|
setTimeout(@proxy(func), timeout || 0)
|
555
549
|
|
550
|
+
# keep controllers elements obj in sync with it contents
|
551
|
+
|
556
552
|
html: (element) ->
|
557
553
|
@el.html(element.el or element)
|
558
554
|
@refreshElements()
|
@@ -576,7 +572,10 @@ class Controller extends Module
|
|
576
572
|
@el
|
577
573
|
|
578
574
|
replace: (element) ->
|
579
|
-
|
575
|
+
element = element.el or element
|
576
|
+
element = $.trim(element) if typeof element is "string"
|
577
|
+
# parseHTML is incompatible with Zepto
|
578
|
+
[previous, @el] = [@el, $($.parseHTML(element)?[0] or element)]
|
580
579
|
previous.replaceWith(@el)
|
581
580
|
@delegateEvents(@events)
|
582
581
|
@refreshElements()
|
@@ -607,7 +606,7 @@ makeArray = (args) ->
|
|
607
606
|
Spine = @Spine = {}
|
608
607
|
module?.exports = Spine
|
609
608
|
|
610
|
-
Spine.version = '1.
|
609
|
+
Spine.version = '1.2.0'
|
611
610
|
Spine.isArray = isArray
|
612
611
|
Spine.isBlank = isBlank
|
613
612
|
Spine.$ = $
|
@@ -5,13 +5,17 @@ Queue = $({})
|
|
5
5
|
|
6
6
|
Ajax =
|
7
7
|
getURL: (object) ->
|
8
|
-
object
|
8
|
+
object.url?() or object.url
|
9
|
+
|
10
|
+
getCollectionURL: (object) ->
|
11
|
+
if object
|
12
|
+
if typeof object.url is "function"
|
13
|
+
@generateURL(object)
|
14
|
+
else
|
15
|
+
object.url
|
9
16
|
|
10
17
|
getScope: (object) ->
|
11
|
-
|
12
|
-
if scope? and scope.charAt(0) is '/'
|
13
|
-
scope = scope.substring(1)
|
14
|
-
scope
|
18
|
+
object.scope?() or object.scope
|
15
19
|
|
16
20
|
generateURL: (object, args...) ->
|
17
21
|
if object.className
|
@@ -20,15 +24,20 @@ Ajax =
|
|
20
24
|
else
|
21
25
|
if typeof object.constructor.url is 'string'
|
22
26
|
collection = object.constructor.url
|
23
|
-
collection = collection.substring(1) if collection.charAt(0) is '/'
|
24
27
|
else
|
25
28
|
collection = object.constructor.className.toLowerCase() + 's'
|
26
29
|
scope = Ajax.getScope(object) or Ajax.getScope(object.constructor)
|
27
30
|
args.unshift(collection)
|
28
|
-
|
29
|
-
|
30
|
-
args.
|
31
|
-
|
31
|
+
args.unshift(scope)
|
32
|
+
# construct and clean url
|
33
|
+
path = args.join('/')
|
34
|
+
path = path.replace /(\/\/)/g, "/"
|
35
|
+
path = path.replace /^\/|\/$/g, ""
|
36
|
+
# handle relative urls vs those that use a host
|
37
|
+
if path.indexOf("../") isnt 0
|
38
|
+
Model.host + "/" + path
|
39
|
+
else
|
40
|
+
path
|
32
41
|
|
33
42
|
enabled: true
|
34
43
|
|
@@ -61,7 +70,7 @@ class Base
|
|
61
70
|
ajax: (params, defaults) ->
|
62
71
|
$.ajax @ajaxSettings(params, defaults)
|
63
72
|
|
64
|
-
ajaxQueue: (params, defaults) ->
|
73
|
+
ajaxQueue: (params, defaults, record) ->
|
65
74
|
jqXHR = null
|
66
75
|
deferred = $.Deferred()
|
67
76
|
promise = deferred.promise()
|
@@ -69,6 +78,13 @@ class Base
|
|
69
78
|
settings = @ajaxSettings(params, defaults)
|
70
79
|
|
71
80
|
request = (next) ->
|
81
|
+
if record?.id?
|
82
|
+
# for existing singleton, model id may have been updated
|
83
|
+
# after request has been queued
|
84
|
+
settings.url ?= Ajax.getURL(record)
|
85
|
+
settings.data?.id = record.id
|
86
|
+
|
87
|
+
settings.data = JSON.stringify(settings.data)
|
72
88
|
jqXHR = $.ajax(settings)
|
73
89
|
.done(deferred.resolve)
|
74
90
|
.fail(deferred.reject)
|
@@ -93,30 +109,30 @@ class Base
|
|
93
109
|
class Collection extends Base
|
94
110
|
constructor: (@model) ->
|
95
111
|
|
96
|
-
find: (id, params) ->
|
112
|
+
find: (id, params, options = {}) ->
|
97
113
|
record = new @model(id: id)
|
98
114
|
@ajaxQueue(
|
99
115
|
params,
|
100
116
|
type: 'GET',
|
101
|
-
url:
|
117
|
+
url: options.url or Ajax.getURL(record)
|
102
118
|
).done(@recordsResponse)
|
103
119
|
.fail(@failResponse)
|
104
120
|
|
105
|
-
all: (params) ->
|
121
|
+
all: (params, options = {}) ->
|
106
122
|
@ajaxQueue(
|
107
123
|
params,
|
108
124
|
type: 'GET',
|
109
|
-
url:
|
125
|
+
url: options.url or Ajax.getURL(@model)
|
110
126
|
).done(@recordsResponse)
|
111
127
|
.fail(@failResponse)
|
112
128
|
|
113
129
|
fetch: (params = {}, options = {}) ->
|
114
130
|
if id = params.id
|
115
131
|
delete params.id
|
116
|
-
@find(id, params).done (record) =>
|
132
|
+
@find(id, params, options).done (record) =>
|
117
133
|
@model.refresh(record, options)
|
118
134
|
else
|
119
|
-
@all(params).done (records) =>
|
135
|
+
@all(params, options).done (records) =>
|
120
136
|
@model.refresh(records, options)
|
121
137
|
|
122
138
|
# Private
|
@@ -131,39 +147,42 @@ class Singleton extends Base
|
|
131
147
|
constructor: (@record) ->
|
132
148
|
@model = @record.constructor
|
133
149
|
|
134
|
-
reload: (params, options) ->
|
150
|
+
reload: (params, options = {}) ->
|
135
151
|
@ajaxQueue(
|
136
|
-
params,
|
137
|
-
|
138
|
-
|
152
|
+
params, {
|
153
|
+
type: 'GET'
|
154
|
+
url: options.url
|
155
|
+
}, @record
|
139
156
|
).done(@recordResponse(options))
|
140
157
|
.fail(@failResponse(options))
|
141
158
|
|
142
|
-
create: (params, options) ->
|
159
|
+
create: (params, options = {}) ->
|
143
160
|
@ajaxQueue(
|
144
161
|
params,
|
145
162
|
type: 'POST'
|
146
163
|
contentType: 'application/json'
|
147
|
-
data:
|
148
|
-
url:
|
164
|
+
data: @record.toJSON()
|
165
|
+
url: options.url or Ajax.getCollectionURL(@record)
|
149
166
|
).done(@recordResponse(options))
|
150
167
|
.fail(@failResponse(options))
|
151
168
|
|
152
|
-
update: (params, options) ->
|
169
|
+
update: (params, options = {}) ->
|
153
170
|
@ajaxQueue(
|
154
|
-
params,
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
171
|
+
params, {
|
172
|
+
type: 'PUT'
|
173
|
+
contentType: 'application/json'
|
174
|
+
data: @record.toJSON()
|
175
|
+
url: options.url
|
176
|
+
}, @record
|
159
177
|
).done(@recordResponse(options))
|
160
178
|
.fail(@failResponse(options))
|
161
179
|
|
162
|
-
destroy: (params, options) ->
|
180
|
+
destroy: (params, options = {}) ->
|
163
181
|
@ajaxQueue(
|
164
|
-
params,
|
165
|
-
|
166
|
-
|
182
|
+
params, {
|
183
|
+
type: 'DELETE'
|
184
|
+
url: options.url
|
185
|
+
}, @record
|
167
186
|
).done(@recordResponse(options))
|
168
187
|
.fail(@failResponse(options))
|
169
188
|
|
@@ -171,18 +190,14 @@ class Singleton extends Base
|
|
171
190
|
|
172
191
|
recordResponse: (options = {}) =>
|
173
192
|
(data, status, xhr) =>
|
174
|
-
if Spine.isBlank(data) or @record.destroyed
|
175
|
-
data = false
|
176
|
-
else
|
177
|
-
data = @model.fromJSON(data)
|
178
193
|
|
179
194
|
Ajax.disable =>
|
180
|
-
|
195
|
+
unless Spine.isBlank(data) or @record.destroyed
|
181
196
|
# ID change, need to do some shifting
|
182
197
|
if data.id and @record.id isnt data.id
|
183
198
|
@record.changeID(data.id)
|
184
199
|
# Update with latest data
|
185
|
-
@record.
|
200
|
+
@record.refresh(data)
|
186
201
|
|
187
202
|
@record.trigger('ajaxSuccess', data, status, xhr)
|
188
203
|
options.success?.apply(@record) # Deprecated
|
@@ -233,5 +248,8 @@ Model.Ajax.Methods =
|
|
233
248
|
|
234
249
|
# Globals
|
235
250
|
Ajax.defaults = Base::defaults
|
251
|
+
Ajax.Base = Base
|
252
|
+
Ajax.Singleton = Singleton
|
253
|
+
Ajax.Collection = Collection
|
236
254
|
Spine.Ajax = Ajax
|
237
255
|
module?.exports = Ajax
|
File without changes
|
@@ -9,8 +9,9 @@ Spine.Model.Local =
|
|
9
9
|
result = JSON.stringify(@)
|
10
10
|
localStorage[@className] = result
|
11
11
|
|
12
|
-
loadLocal: ->
|
12
|
+
loadLocal: (options = {})->
|
13
|
+
options.clear = true unless options.hasOwnProperty('clear')
|
13
14
|
result = localStorage[@className]
|
14
|
-
@refresh(result or [],
|
15
|
+
@refresh(result or [], options)
|
15
16
|
|
16
17
|
module?.exports = Spine.Model.Local
|
@@ -26,11 +26,10 @@ class Spine.Manager extends Spine.Module
|
|
26
26
|
# Private
|
27
27
|
|
28
28
|
change: (current, args...) ->
|
29
|
-
for cont in @controllers
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
cont.deactivate(args...)
|
29
|
+
for cont in @controllers when cont isnt current
|
30
|
+
cont.deactivate(args...)
|
31
|
+
|
32
|
+
current.activate(args...) if current
|
34
33
|
|
35
34
|
Spine.Controller.include
|
36
35
|
active: (args...) ->
|
@@ -81,4 +80,4 @@ class Spine.Stack extends Spine.Controller
|
|
81
80
|
@append(controller)
|
82
81
|
|
83
82
|
module?.exports = Spine.Manager
|
84
|
-
module?.exports.Stack = Spine.Stack
|
83
|
+
module?.exports.Stack = Spine.Stack
|
File without changes
|
@@ -18,6 +18,7 @@ class Spine.Route extends Spine.Module
|
|
18
18
|
history: false
|
19
19
|
shim: false
|
20
20
|
replace: false
|
21
|
+
redirect: false
|
21
22
|
|
22
23
|
@add: (path, callback) ->
|
23
24
|
if (typeof path is 'object' and path not instanceof RegExp)
|
@@ -64,10 +65,17 @@ class Spine.Route extends Spine.Module
|
|
64
65
|
|
65
66
|
@trigger('navigate', @path)
|
66
67
|
|
67
|
-
@matchRoute(@path, options) if options.trigger
|
68
|
+
route = @matchRoute(@path, options) if options.trigger
|
68
69
|
|
69
70
|
return if options.shim
|
70
71
|
|
72
|
+
if !route
|
73
|
+
if typeof options.redirect is 'function'
|
74
|
+
return options.redirect.apply this, [@path, options]
|
75
|
+
else
|
76
|
+
if options.redirect is true
|
77
|
+
@redirect(@path)
|
78
|
+
|
71
79
|
if @history and options.replace
|
72
80
|
history.replaceState({}, document.title, @path)
|
73
81
|
else if @history
|
@@ -100,6 +108,9 @@ class Spine.Route extends Spine.Module
|
|
100
108
|
@trigger('change', route, path)
|
101
109
|
return route
|
102
110
|
|
111
|
+
@redirect: (path) ->
|
112
|
+
window.location = path
|
113
|
+
|
103
114
|
constructor: (@path, @callback) ->
|
104
115
|
@names = []
|
105
116
|
|
metadata
CHANGED
@@ -1,62 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: spine-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
5
|
-
prerelease:
|
4
|
+
version: 0.1.2
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Alex MacCaw
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2013-
|
11
|
+
date: 2013-09-25 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rails
|
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.1.0
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: 3.1.0
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: json2-rails
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - '>='
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: 0.0.2
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - '>='
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: 0.0.2
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: bundler
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- -
|
45
|
+
- - '>='
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '0'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- -
|
52
|
+
- - '>='
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '0'
|
62
55
|
description: This gem provides Spine for your Rails 3 application.
|
@@ -104,26 +97,25 @@ files:
|
|
104
97
|
- vendor/assets/javascripts/spine/route.coffee
|
105
98
|
homepage: http://rubygems.org/gems/spine-rails
|
106
99
|
licenses: []
|
100
|
+
metadata: {}
|
107
101
|
post_install_message:
|
108
102
|
rdoc_options: []
|
109
103
|
require_paths:
|
110
104
|
- lib
|
111
105
|
required_ruby_version: !ruby/object:Gem::Requirement
|
112
|
-
none: false
|
113
106
|
requirements:
|
114
|
-
- -
|
107
|
+
- - '>='
|
115
108
|
- !ruby/object:Gem::Version
|
116
109
|
version: '0'
|
117
110
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
118
|
-
none: false
|
119
111
|
requirements:
|
120
|
-
- -
|
112
|
+
- - '>='
|
121
113
|
- !ruby/object:Gem::Version
|
122
114
|
version: 1.3.6
|
123
115
|
requirements: []
|
124
116
|
rubyforge_project: spine-rails
|
125
|
-
rubygems_version:
|
117
|
+
rubygems_version: 2.0.3
|
126
118
|
signing_key:
|
127
|
-
specification_version:
|
119
|
+
specification_version: 4
|
128
120
|
summary: Use Spine with Rails 3
|
129
121
|
test_files: []
|