sisyphus-rails 0.0.1 → 0.0.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.
data/README.md CHANGED
@@ -47,7 +47,7 @@ To stop Sisyphus from initializing on a form include the *with_sisyphus* option
47
47
  ## Dependencies
48
48
 
49
49
  - Rails >= 3.1
50
- - Jquery
50
+ - Jquery 1.8+
51
51
 
52
52
  ## TODO
53
53
 
@@ -68,6 +68,8 @@ To stop Sisyphus from initializing on a form include the *with_sisyphus* option
68
68
 
69
69
  ## Contributing
70
70
 
71
+ If you have time to tackle something off the TODO list before I manage to get around to it then please do!
72
+
71
73
  1. Fork it
72
74
  2. Create your feature branch (`git checkout -b my-new-feature`)
73
75
  3. Commit your changes (`git commit -am 'Add some feature'`)
@@ -6,7 +6,7 @@ module ActionView
6
6
  buf = ActiveSupport::SafeBuffer.new
7
7
 
8
8
  if options.has_key?(:id) && Sisyphus::process
9
- buf.safe_concat("<script type=\"text/javascript\">$(document).ready(function() {$('##{options[:id]}').sisyphus();});</script>")
9
+ buf.safe_concat("<script type=\"text/javascript\">$(document).ready(function() {$('##{options[:id]}').sisyphus({excludeFields: $('input[name=utf8], input[name=_method], input[name=authenticity_token]')});});</script>")
10
10
  end
11
11
 
12
12
  buf << form_tag_without_sisyphus(url_for_options, options, &block)
@@ -15,4 +15,4 @@ module ActionView
15
15
  alias_method_chain :form_tag, :sisyphus
16
16
  end
17
17
  end
18
- end
18
+ end
@@ -1,5 +1,5 @@
1
1
  module Sisyphus
2
2
  module Rails
3
- VERSION = "0.0.1"
3
+ VERSION = "0.0.2"
4
4
  end
5
5
  end
@@ -16,6 +16,9 @@ Gem::Specification.new do |gem|
16
16
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
17
17
  gem.require_paths = ["lib"]
18
18
 
19
- gem.add_dependency "railties", "~> 3.1"
20
- gem.add_dependency "jquery-rails"
19
+ gem.requirements << 'requires jQuery 1.4+ to be included before Sisyphus'
20
+ gem.requirements << 'requires jQuery 1.8+ to be included if you require jStorage'
21
+
22
+ gem.add_dependency "rails", ">= 3.1.0"
21
23
  end
24
+
@@ -1 +1,459 @@
1
- (function(a){a.sisyphus=function(){return Sisyphus.getInstance()},a.fn.sisyphus=function(a){var b=Sisyphus.getInstance();return b.setOptions(a),b.protect(this),b};var b={};b.isAvailable=function(){if(typeof a.jStorage=="object")return!0;try{return localStorage.getItem}catch(b){return!1}},b.set=function(b,c){if(typeof a.jStorage=="object")a.jStorage.set(b,c+"");else try{localStorage.setItem(b,c+"")}catch(d){}},b.get=function(b){if(typeof a.jStorage=="object"){var c=a.jStorage.get(b);return c?c.toString():c}return localStorage.getItem(b)},b.remove=function(b){typeof a.jStorage=="object"?a.jStorage.deleteKey(b):localStorage.removeItem(b)},Sisyphus=function(){function d(){return{setInitialOptions:function(c){var d={excludeFields:[],customKeyPrefix:"",timeout:0,autoRelease:!0,name:null,onSave:function(){},onBeforeRestore:function(){},onRestore:function(){},onRelease:function(){}};this.options=this.options||a.extend(d,c),this.browserStorage=b},setOptions:function(b){this.options=this.options||this.setInitialOptions(b),this.options=a.extend(this.options,b)},protect:function(b){b=b||{};var d=this;this.targets=this.targets||[],this.href=this.options.name||location.hostname+location.pathname+location.search+location.hash,this.targets=a.merge(this.targets,b),this.targets=a.unique(this.targets),this.targets=a(this.targets);if(!this.browserStorage.isAvailable())return!1;d.restoreAllData(),this.options.autoRelease&&d.bindReleaseData(),c.started||(d.bindSaveData(),c.started=!0)},bindSaveData:function(){var b=this;b.options.timeout&&b.saveDataByTimeout(),b.targets.each(function(){var c=a(this).attr("id"),d=a(this).find(":input").not(":submit").not(":reset").not(":button").not(":file");d.each(function(){if(a.inArray(this,b.options.excludeFields)!==-1)return!0;var d=a(this),e=b.href+c+d.attr("name")+b.options.customKeyPrefix;d.is(":text")||d.is("textarea")?b.options.timeout||b.bindSaveDataImmediately(d,e):b.bindSaveDataOnChange(d,e)})})},saveAllData:function(){var b=this;b.targets.each(function(){var c=a(this).attr("id"),d=a(this).find(":input").not(":submit").not(":reset").not(":button").not(":file");d.each(function(){var d=a(this);if(a.inArray(this,b.options.excludeFields)!==-1||d.attr("name")===undefined)return!0;var e=b.href+c+d.attr("name")+b.options.customKeyPrefix,f=d.val();d.is(":checkbox")?(d.attr("name").indexOf("[")!==-1?(f=[],a("[name='"+d.attr("name")+"']:checked").each(function(){f.push(a(this).val())})):f=d.is(":checked"),b.saveToBrowserStorage(e,f,!1)):d.is(":radio")?d.is(":checked")&&(f=d.val(),b.saveToBrowserStorage(e,f,!1)):b.saveToBrowserStorage(e,f,!1)})}),a.isFunction(b.options.onSave)&&b.options.onSave.call()},restoreAllData:function(){var b=this,c=!1;a.isFunction(b.options.onBeforeRestore)&&b.options.onBeforeRestore.call(),b.targets.each(function(){var d=a(this),e=d.attr("id"),f=d.find(":input").not(":submit").not(":reset").not(":button").not(":file");f.each(function(){if(a.inArray(this,b.options.excludeFields)!==-1)return!0;var d=a(this),f=b.href+e+d.attr("name")+b.options.customKeyPrefix,g=b.browserStorage.get(f);g&&(b.restoreFieldsData(d,g),c=!0)})}),c&&a.isFunction(b.options.onRestore)&&b.options.onRestore.call()},restoreFieldsData:function(a,b){if(a.attr("name")===undefined)return!1;a.is(":checkbox")&&b!=="false"&&a.attr("name").indexOf("[")===-1?a.attr("checked","checked"):a.is(":radio")?a.val()===b&&a.attr("checked","checked"):a.attr("name").indexOf("[")===-1?a.val(b):(b=b.split(","),a.val(b))},bindSaveDataImmediately:function(b,c){var d=this;a.browser.msie===null?b.get(0).oninput=function(){d.saveToBrowserStorage(c,b.val())}:b.get(0).onpropertychange=function(){d.saveToBrowserStorage(c,b.val())}},saveToBrowserStorage:function(b,c,d){d=d===null?!0:d,this.browserStorage.set(b,c),d&&c!==""&&a.isFunction(this.options.onSave)&&this.options.onSave.call()},bindSaveDataOnChange:function(a,b){var c=this;a.change(function(){c.saveAllData()})},saveDataByTimeout:function(){var a=this,b=a.targets;setTimeout(function(b){function c(){a.saveAllData(),setTimeout(c,a.options.timeout*1e3)}return c}(b),a.options.timeout*1e3)},bindReleaseData:function(){var b=this;b.targets.each(function(c){var d=a(this),e=d.find(":input").not(":submit").not(":reset").not(":button").not(":file"),f=d.attr("id");a(this).bind("submit reset",function(){b.releaseData(f,e)})})},manuallyReleaseData:function(){var b=this;b.targets.each(function(c){var d=a(this),e=d.find(":input").not(":submit").not(":reset").not(":button").not(":file"),f=d.attr("id");b.releaseData(f,e)})},releaseData:function(b,c){var d=!1,e=this;c.each(function(){if(a.inArray(this,e.options.excludeFields)!==-1)return!0;var c=a(this),f=e.href+b+c.attr("name")+e.options.customKeyPrefix;e.browserStorage.remove(f),d=!0}),d&&a.isFunction(e.options.onRelease)&&e.options.onRelease.call()}}}var c={instantiated:null,started:null};return{getInstance:function(){return c.instantiated||(c.instantiated=d(),c.instantiated.setInitialOptions()),c.instantiated},free:function(){return c={},null}}}()})(jQuery)
1
+ /**
2
+ * Plugin developed to save html forms data to LocalStorage to restore them after browser crashes, tabs closings
3
+ * and other disasters.
4
+ *
5
+ * @author Alexander Kaupanin <kaupanin@gmail.com>
6
+ */
7
+
8
+ //$.sisyphus().setOptions({timeout: 15})
9
+ ( function( $ ) {
10
+ $.sisyphus = function() {
11
+ return Sisyphus.getInstance();
12
+ };
13
+
14
+ $.fn.sisyphus = function( options ) {
15
+ var sisyphus = Sisyphus.getInstance();
16
+ sisyphus.setOptions( options );
17
+ sisyphus.protect( this );
18
+ return sisyphus;
19
+ };
20
+
21
+ var browserStorage = {};
22
+
23
+ /**
24
+ * Check if local storage or other browser storage is available
25
+ *
26
+ * @return Boolean
27
+ */
28
+ browserStorage.isAvailable = function() {
29
+ if ( typeof $.jStorage === "object" ) {
30
+ return true;
31
+ }
32
+ try {
33
+ return localStorage.getItem;
34
+ } catch ( e ) {
35
+ return false;
36
+ }
37
+ };
38
+
39
+ /**
40
+ * Set data to browser storage
41
+ *
42
+ * @param [String] key
43
+ * @param [String] value
44
+ *
45
+ * @return Boolean
46
+ */
47
+ browserStorage.set = function( key, value ) {
48
+ if ( typeof $.jStorage === "object" ) {
49
+ $.jStorage.set( key, value + "" );
50
+ } else {
51
+ try {
52
+ localStorage.setItem( key, value + "" );
53
+ } catch (e) {
54
+ //QUOTA_EXCEEDED_ERR
55
+ }
56
+ }
57
+ };
58
+
59
+ /**
60
+ * Get data from browser storage by specified key
61
+ *
62
+ * @param [String] key
63
+ *
64
+ * @return string
65
+ */
66
+ browserStorage.get = function( key ) {
67
+ if ( typeof $.jStorage === "object" ) {
68
+ var result = $.jStorage.get( key );
69
+ return result ? result.toString() : result;
70
+ } else {
71
+ return localStorage.getItem( key );
72
+ }
73
+ };
74
+
75
+ /**
76
+ * Delete data from browser storage by specified key
77
+ *
78
+ * @param [String] key
79
+ *
80
+ * @return void
81
+ */
82
+ browserStorage.remove = function( key ) {
83
+ if ( typeof $.jStorage === "object" ) {
84
+ $.jStorage.deleteKey( key );
85
+ } else {
86
+ localStorage.removeItem( key );
87
+ }
88
+ };
89
+
90
+ Sisyphus = ( function() {
91
+ var params = {
92
+ instantiated: null,
93
+ started: null
94
+ };
95
+
96
+ function init () {
97
+
98
+ return {
99
+ /**
100
+ * Set plugin initial options
101
+ *
102
+ * @param [Object] options
103
+ *
104
+ * @return void
105
+ */
106
+ setInitialOptions: function ( options ) {
107
+ var defaults = {
108
+ excludeFields: [],
109
+ customKeyPrefix: "",
110
+ timeout: 0,
111
+ autoRelease: true,
112
+ name: null,
113
+ onSave: function() {},
114
+ onBeforeRestore: function() {},
115
+ onRestore: function() {},
116
+ onRelease: function() {}
117
+ };
118
+ this.options = this.options || $.extend( defaults, options );
119
+ this.browserStorage = browserStorage;
120
+ },
121
+
122
+ /**
123
+ * Set plugin options
124
+ *
125
+ * @param [Object] options
126
+ *
127
+ * @return void
128
+ */
129
+ setOptions: function ( options ) {
130
+ this.options = this.options || this.setInitialOptions( options );
131
+ this.options = $.extend( this.options, options );
132
+ },
133
+
134
+ /**
135
+ * Protect specified forms, store it's fields data to local storage and restore them on page load
136
+ *
137
+ * @param [Object] targets forms object(s), result of jQuery selector
138
+ * @param Object options plugin options
139
+ *
140
+ * @return void
141
+ */
142
+ protect: function( targets ) {
143
+ targets = targets || {};
144
+ var self = this;
145
+ this.targets = this.targets || [];
146
+ this.href = this.options.name || location.hostname + location.pathname + location.search + location.hash;
147
+
148
+ this.targets = $.merge( this.targets, targets );
149
+ this.targets = $.unique( this.targets );
150
+ this.targets = $( this.targets );
151
+ if ( ! this.browserStorage.isAvailable() ) {
152
+ return false;
153
+ }
154
+
155
+ self.restoreAllData();
156
+ if ( this.options.autoRelease ) {
157
+ self.bindReleaseData();
158
+ }
159
+ if ( ! params.started ) {
160
+ self.bindSaveData();
161
+ params.started = true;
162
+ }
163
+ },
164
+
165
+ /**
166
+ * Bind saving data
167
+ *
168
+ * @return void
169
+ */
170
+ bindSaveData: function() {
171
+ var self = this;
172
+
173
+ if ( self.options.timeout ) {
174
+ self.saveDataByTimeout();
175
+ }
176
+
177
+ self.targets.each( function() {
178
+ var targetFormId = $( this ).attr( "id" );
179
+ var fieldsToProtect = $( this ).find( ":input" ).not( ":submit" ).not( ":reset" ).not( ":button" ).not( ":file" );
180
+
181
+ fieldsToProtect.each( function() {
182
+ if ( $.inArray( this, self.options.excludeFields ) !== -1 ) {
183
+ // Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
184
+ return true;
185
+ }
186
+ var field = $( this );
187
+ var prefix = self.href + targetFormId + field.attr( "name" ) + self.options.customKeyPrefix;
188
+ if ( field.is( ":text" ) || field.is( "textarea" ) ) {
189
+ if ( ! self.options.timeout ) {
190
+ self.bindSaveDataImmediately( field, prefix );
191
+ }
192
+ } else {
193
+ self.bindSaveDataOnChange( field, prefix );
194
+ }
195
+ } );
196
+ } );
197
+ },
198
+
199
+ /**
200
+ * Save all protected forms data to Local Storage.
201
+ * Common method, necessary to not lead astray user firing 'data are saved' when select/checkbox/radio
202
+ * is changed and saved, while textfield data are saved only by timeout
203
+ *
204
+ * @return void
205
+ */
206
+ saveAllData: function() {
207
+ var self = this;
208
+ self.targets.each( function() {
209
+ var targetFormId = $( this ).attr( "id" );
210
+ var fieldsToProtect = $( this ).find( ":input" ).not( ":submit" ).not( ":reset" ).not( ":button" ).not( ":file" );
211
+
212
+ fieldsToProtect.each( function() {
213
+ var field = $( this );
214
+ if ( $.inArray( this, self.options.excludeFields ) !== -1 || field.attr( "name" ) === undefined ) {
215
+ // Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
216
+ return true;
217
+ }
218
+ var prefix = self.href + targetFormId + field.attr( "name" ) + self.options.customKeyPrefix;
219
+ var value = field.val();
220
+
221
+ if ( field.is(":checkbox") ) {
222
+ if ( field.attr( "name" ).indexOf( "[" ) !== -1 ) {
223
+ value = [];
224
+ $( "[name='" + field.attr( "name" ) +"']:checked" ).each( function() {
225
+ value.push( $( this ).val() );
226
+ } );
227
+ } else {
228
+ value = field.is( ":checked" );
229
+ }
230
+ self.saveToBrowserStorage( prefix, value, false );
231
+ } else if ( field.is( ":radio" ) ) {
232
+ if ( field.is( ":checked" ) ) {
233
+ value = field.val();
234
+ self.saveToBrowserStorage( prefix, value, false );
235
+ }
236
+ } else {
237
+ self.saveToBrowserStorage( prefix, value, false );
238
+ }
239
+ } );
240
+ } );
241
+ if ( $.isFunction( self.options.onSave ) ) {
242
+ self.options.onSave.call();
243
+ }
244
+ },
245
+
246
+ /**
247
+ * Restore forms data from Local Storage
248
+ *
249
+ * @return void
250
+ */
251
+ restoreAllData: function() {
252
+ var self = this;
253
+ var restored = false;
254
+
255
+ if ( $.isFunction( self.options.onBeforeRestore ) ) {
256
+ self.options.onBeforeRestore.call();
257
+ }
258
+
259
+ self.targets.each( function() {
260
+ var target = $( this );
261
+ var targetFormId = target.attr( "id" );
262
+ var fieldsToProtect = target.find( ":input" ).not( ":submit" ).not( ":reset" ).not( ":button" ).not( ":file" );
263
+
264
+ fieldsToProtect.each( function() {
265
+
266
+ if ( $.inArray( this, self.options.excludeFields ) !== -1 ) {
267
+ // Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
268
+ return true;
269
+ }
270
+ var field = $( this );
271
+ var prefix = self.href + targetFormId + field.attr( "name" ) + self.options.customKeyPrefix;
272
+ var resque = self.browserStorage.get( prefix );
273
+ if ( resque ) {
274
+ self.restoreFieldsData( field, resque );
275
+ restored = true;
276
+ }
277
+ } );
278
+ } );
279
+
280
+ if ( restored && $.isFunction( self.options.onRestore ) ) {
281
+ self.options.onRestore.call();
282
+ }
283
+ },
284
+
285
+ /**
286
+ * Restore form field data from local storage
287
+ *
288
+ * @param Object field jQuery form element object
289
+ * @param String resque previously stored fields data
290
+ *
291
+ * @return void
292
+ */
293
+ restoreFieldsData: function( field, resque ) {
294
+ if ( field.attr( "name" ) === undefined ) {
295
+ return false;
296
+ }
297
+ if ( field.is( ":checkbox" ) && resque !== "false" && field.attr( "name" ).indexOf( "[" ) === -1 ) {
298
+ field.attr( "checked", "checked" );
299
+ } else if ( field.is( ":radio" ) ) {
300
+ if ( field.val() === resque ) {
301
+ field.attr( "checked", "checked" );
302
+ }
303
+ } else if ( field.attr( "name" ).indexOf( "[" ) === -1 ) {
304
+ field.val( resque );
305
+ } else {
306
+ resque = resque.split( "," );
307
+ field.val( resque );
308
+ }
309
+ },
310
+
311
+ /**
312
+ * Bind immediate saving (on typing/checking/changing) field data to local storage when user fills it
313
+ *
314
+ * @param Object field jQuery form element object
315
+ * @param String prefix prefix used as key to store data in local storage
316
+ *
317
+ * @return void
318
+ */
319
+ bindSaveDataImmediately: function( field, prefix ) {
320
+ var self = this;
321
+ if ( typeof $.browser.msie === 'undefined' ) {
322
+ field.get(0).oninput = function() {
323
+ self.saveToBrowserStorage( prefix, field.val() );
324
+ };
325
+ } else {
326
+ field.get(0).onpropertychange = function() {
327
+ self.saveToBrowserStorage( prefix, field.val() );
328
+ };
329
+ }
330
+ },
331
+
332
+ /**
333
+ * Save data to Local Storage and fire callback if defined
334
+ *
335
+ * @param String key
336
+ * @param String value
337
+ * @param Boolean [true] fireCallback
338
+ *
339
+ * @return void
340
+ */
341
+ saveToBrowserStorage: function( key, value, fireCallback ) {
342
+ // if fireCallback is undefined it should be true
343
+ fireCallback = fireCallback === null ? true : fireCallback;
344
+ this.browserStorage.set( key, value );
345
+ if ( fireCallback && value !== "" && $.isFunction( this.options.onSave ) ) {
346
+ this.options.onSave.call();
347
+ }
348
+ },
349
+
350
+ /**
351
+ * Bind saving field data on change
352
+ *
353
+ * @param Object field jQuery form element object
354
+ * @param String prefix prefix used as key to store data in local storage
355
+ *
356
+ * @return void
357
+ */
358
+ bindSaveDataOnChange: function( field, prefix ) {
359
+ var self = this;
360
+ field.change( function() {
361
+ self.saveAllData();
362
+ } );
363
+ },
364
+
365
+ /**
366
+ * Saving (by timeout) field data to local storage when user fills it
367
+ *
368
+ * @return void
369
+ */
370
+ saveDataByTimeout: function() {
371
+ var self = this;
372
+ var targetForms = self.targets;
373
+ setTimeout( ( function( targetForms ) {
374
+ function timeout() {
375
+ self.saveAllData();
376
+ setTimeout( timeout, self.options.timeout * 1000 );
377
+ }
378
+ return timeout;
379
+ } )( targetForms ), self.options.timeout * 1000 );
380
+ },
381
+
382
+ /**
383
+ * Bind release form fields data from local storage on submit/reset form
384
+ *
385
+ * @return void
386
+ */
387
+ bindReleaseData: function() {
388
+ var self = this;
389
+ self.targets.each( function( i ) {
390
+ var target = $( this );
391
+ var fieldsToProtect = target.find( ":input" ).not( ":submit" ).not( ":reset" ).not( ":button" ).not( ":file" );
392
+ var formId = target.attr( "id" );
393
+ $( this ).bind( "submit reset", function() {
394
+ self.releaseData( formId, fieldsToProtect );
395
+ } );
396
+ } );
397
+ },
398
+
399
+ /**
400
+ * Manually release form fields
401
+ *
402
+ * @return void
403
+ */
404
+ manuallyReleaseData: function() {
405
+ var self = this;
406
+ self.targets.each( function( i ) {
407
+ var target = $( this );
408
+ var fieldsToProtect = target.find( ":input" ).not( ":submit" ).not( ":reset" ).not( ":button" ).not( ":file" );
409
+ var formId = target.attr( "id" );
410
+ self.releaseData( formId, fieldsToProtect );
411
+ } );
412
+ },
413
+
414
+ /**
415
+ * Bind release form fields data from local storage on submit/resett form
416
+ *
417
+ * @param String targetFormId
418
+ * @param Object fieldsToProtect jQuery object contains form fields to protect
419
+ *
420
+ * @return void
421
+ */
422
+ releaseData: function( targetFormId, fieldsToProtect ) {
423
+ var released = false;
424
+ var self = this;
425
+ fieldsToProtect.each( function() {
426
+ if ( $.inArray( this, self.options.excludeFields ) !== -1 ) {
427
+ // Returning non-false is the same as a continue statement in a for loop; it will skip immediately to the next iteration.
428
+ return true;
429
+ }
430
+ var field = $( this );
431
+ var prefix = self.href + targetFormId + field.attr( "name" ) + self.options.customKeyPrefix;
432
+ self.browserStorage.remove( prefix );
433
+ released = true;
434
+ } );
435
+
436
+ if ( released && $.isFunction( self.options.onRelease ) ) {
437
+ self.options.onRelease.call();
438
+ }
439
+ }
440
+
441
+ };
442
+ }
443
+
444
+ return {
445
+ getInstance: function() {
446
+ if ( ! params.instantiated ) {
447
+ params.instantiated = init();
448
+ params.instantiated.setInitialOptions();
449
+ }
450
+ return params.instantiated;
451
+ },
452
+
453
+ free: function() {
454
+ params = {};
455
+ return null;
456
+ }
457
+ };
458
+ } )();
459
+ } )( jQuery );
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sisyphus-rails
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,29 +12,13 @@ cert_chain: []
12
12
  date: 2012-10-02 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
- name: railties
16
- requirement: !ruby/object:Gem::Requirement
17
- none: false
18
- requirements:
19
- - - ~>
20
- - !ruby/object:Gem::Version
21
- version: '3.1'
22
- type: :runtime
23
- prerelease: false
24
- version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
- requirements:
27
- - - ~>
28
- - !ruby/object:Gem::Version
29
- version: '3.1'
30
- - !ruby/object:Gem::Dependency
31
- name: jquery-rails
15
+ name: rails
32
16
  requirement: !ruby/object:Gem::Requirement
33
17
  none: false
34
18
  requirements:
35
19
  - - ! '>='
36
20
  - !ruby/object:Gem::Version
37
- version: '0'
21
+ version: 3.1.0
38
22
  type: :runtime
39
23
  prerelease: false
40
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -42,7 +26,7 @@ dependencies:
42
26
  requirements:
43
27
  - - ! '>='
44
28
  - !ruby/object:Gem::Version
45
- version: '0'
29
+ version: 3.1.0
46
30
  description: Include gmail like auto-save on your forms
47
31
  email:
48
32
  - devon.noonan@gmail.com
@@ -75,13 +59,21 @@ required_ruby_version: !ruby/object:Gem::Requirement
75
59
  - - ! '>='
76
60
  - !ruby/object:Gem::Version
77
61
  version: '0'
62
+ segments:
63
+ - 0
64
+ hash: -93684305
78
65
  required_rubygems_version: !ruby/object:Gem::Requirement
79
66
  none: false
80
67
  requirements:
81
68
  - - ! '>='
82
69
  - !ruby/object:Gem::Version
83
70
  version: '0'
84
- requirements: []
71
+ segments:
72
+ - 0
73
+ hash: -93684305
74
+ requirements:
75
+ - requires jQuery 1.4+ to be included before Sisyphus
76
+ - requires jQuery 1.8+ to be included if you require jStorage
85
77
  rubyforge_project:
86
78
  rubygems_version: 1.8.24
87
79
  signing_key: