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.
@@ -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
@@ -1,4 +1,4 @@
1
- TAG=v1.1.0
1
+ TAG=v1.2.0
2
2
  FILES=( ajax list local manager relation route )
3
3
  curl -s -o vendor/assets/javascripts/spine.coffee https://raw.github.com/spine/spine/$TAG/src/spine.coffee
4
4
 
@@ -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: 'List of model attributes', type: :array, banner: 'field1 field2'
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: :string, default: "app", desc: "app name"
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: "//= require_tree ." do
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
@@ -1,7 +1,7 @@
1
1
  module Spine
2
2
  module Generators
3
3
  class Base < ::Rails::Generators::NamedBase
4
- class_option :app, type: :string, default: "app", desc: "app name"
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
@@ -1,6 +1,6 @@
1
1
  module Spine
2
2
  module Rails
3
- VERSION = "0.1.1"
4
- SPINE_VERSION = "1.1.0"
3
+ VERSION = "0.1.2"
4
+ SPINE_VERSION = "1.2.0"
5
5
  end
6
6
  end
@@ -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
- listeningToOnce.push obj
33
- obj.one ev, ->
34
- idx = listeningToOnce.indexOf(obj)
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, ev, callback) ->
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 obj in listeningTo when not (obj in retain)
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
- idx = listeningTo.indexOf(obj)
56
- listeningTo.splice(idx, 1) unless idx is -1
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
- @crecords: {}
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
- (@records[id] ? @irecords[id])?.clone()
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', @cloneArray(records))
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
- @records
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
- destroy: (options = {}) ->
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.crecords[@cid]
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
- result = new @constructor(@attributes())
353
- if newRecord is false
354
- result.cid = @cid
360
+ dup: (newRecord = true) ->
361
+ atts = @attributes()
362
+ if newRecord
363
+ delete atts.id
355
364
  else
356
- delete result.id
357
- result
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 = @cid unless @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: (obj, events, callback) ->
439
- obj.bind events, callback
440
- @listeningTo or= []
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.delegate(selector, eventName, method)
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
- [previous, @el] = [@el, $(element.el or element)]
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.1.0'
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 and object.url?() or object.url
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
- scope = object and object.scope?() or object.scope
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
- if scope?
29
- args.unshift(scope)
30
- args.unshift(Model.host)
31
- args.join('/')
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: Ajax.getURL(record)
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: Ajax.getURL(@model)
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
- type: 'GET'
138
- url: Ajax.getURL(@record)
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: JSON.stringify(@record)
148
- url: Ajax.getURL(@model)
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
- type: 'PUT'
156
- contentType: 'application/json'
157
- data: JSON.stringify(@record)
158
- url: Ajax.getURL(@record)
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
- type: 'DELETE'
166
- url: Ajax.getURL(@record)
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
- if data
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.updateAttributes(data.attributes())
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
@@ -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 [], clear: true)
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
- if cont is current
31
- cont.activate(args...)
32
- else
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
@@ -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.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-06-11 00:00:00.000000000 Z
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: 1.8.24
117
+ rubygems_version: 2.0.3
126
118
  signing_key:
127
- specification_version: 3
119
+ specification_version: 4
128
120
  summary: Use Spine with Rails 3
129
121
  test_files: []