spine-rails 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|