sooner 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. data/MIT-LICENSE +1 -1
  2. data/README.rdoc +0 -0
  3. data/Rakefile +28 -32
  4. data/app/assets/javascripts/sooner/admin/application.js +8 -0
  5. data/app/assets/javascripts/sooner/application.js +2 -0
  6. data/app/assets/javascripts/sooner/jquery.tablesorter.min.js +4 -0
  7. data/app/assets/javascripts/sooner/subscribers.js +2 -0
  8. data/app/assets/stylesheets/sooner/admin/application.css +37 -0
  9. data/app/assets/stylesheets/sooner/application.css +3 -0
  10. data/app/assets/stylesheets/sooner/subscribers.css +0 -0
  11. data/app/controllers/sooner/admin/subscribers_controller.rb +89 -0
  12. data/app/controllers/sooner/application_controller.rb +4 -0
  13. data/app/controllers/sooner/subscribers_controller.rb +20 -16
  14. data/app/helpers/sooner/admin/subscribers_helper.rb +4 -0
  15. data/app/helpers/sooner/application_helper.rb +4 -0
  16. data/app/helpers/sooner/subscribers_helper.rb +4 -0
  17. data/app/mailers/sooner/subscribers_mailer.rb +16 -0
  18. data/app/models/sooner/admin/subscriber.rb +3 -0
  19. data/app/models/sooner/subscriber.rb +19 -12
  20. data/app/views/layouts/sooner/admin.html.erb +21 -0
  21. data/app/views/layouts/sooner/application.html.erb +14 -0
  22. data/app/views/sooner/admin/subscribers/_form.html.erb +19 -0
  23. data/app/views/sooner/admin/subscribers/edit.html.erb +6 -0
  24. data/app/views/sooner/admin/subscribers/index.html.erb +22 -0
  25. data/app/views/sooner/admin/subscribers/new.html.erb +8 -0
  26. data/app/views/sooner/admin/subscribers/show.html.erb +5 -0
  27. data/app/views/sooner/subscribers/_message.html.erb +1 -0
  28. data/app/views/sooner/subscribers/create.js.erb +5 -0
  29. data/app/views/sooner/subscribers/new.html.erb +17 -10
  30. data/app/views/sooner/subscribers_mailer/subscribed.text.erb +3 -0
  31. data/config/routes.rb +8 -3
  32. data/lib/generators/sooner/install/install_generator.rb +33 -32
  33. data/lib/generators/sooner/install/templates/README +3 -13
  34. data/lib/generators/sooner/views/views_generator.rb +49 -47
  35. data/lib/sooner/engine.rb +5 -0
  36. data/lib/sooner/version.rb +2 -2
  37. data/lib/sooner/version.rb~ +3 -0
  38. data/lib/sooner.rb +21 -12
  39. data/lib/tasks/sooner_tasks.rake +4 -0
  40. data/test/dummy/Rakefile +7 -0
  41. data/test/dummy/app/assets/javascripts/application.js +9 -0
  42. data/test/dummy/app/assets/stylesheets/application.css +7 -0
  43. data/test/dummy/app/controllers/application_controller.rb +3 -0
  44. data/test/dummy/app/helpers/application_helper.rb +2 -0
  45. data/test/dummy/app/views/layouts/application.html.erb +14 -0
  46. data/test/dummy/config/application.rb +45 -0
  47. data/test/dummy/config/boot.rb +10 -0
  48. data/test/dummy/config/database.yml +25 -0
  49. data/test/dummy/config/environment.rb +5 -0
  50. data/test/dummy/config/environments/development.rb +33 -0
  51. data/test/dummy/config/environments/production.rb +60 -0
  52. data/test/dummy/config/environments/test.rb +39 -0
  53. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  54. data/test/dummy/config/initializers/inflections.rb +10 -0
  55. data/test/dummy/config/initializers/mime_types.rb +5 -0
  56. data/test/dummy/config/initializers/secret_token.rb +7 -0
  57. data/test/dummy/config/initializers/session_store.rb +8 -0
  58. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  59. data/test/dummy/config/locales/en.yml +5 -0
  60. data/test/dummy/config/mongoid.yml +20 -0
  61. data/test/dummy/config/routes.rb +3 -0
  62. data/test/dummy/config.ru +4 -0
  63. data/test/dummy/db/development.sqlite3 +0 -0
  64. data/test/dummy/log/development.log +13370 -0
  65. data/test/dummy/public/404.html +26 -0
  66. data/test/dummy/public/422.html +26 -0
  67. data/test/dummy/public/500.html +26 -0
  68. data/test/dummy/public/favicon.ico +0 -0
  69. data/test/dummy/public/subscribers.csv +1 -0
  70. data/test/dummy/script/rails +6 -0
  71. data/test/dummy/tmp/cache/assets/C30/8B0/sprockets%2F6853748309a0fdd864824f56536d8023 +9062 -0
  72. data/test/dummy/tmp/cache/assets/C3F/0E0/sprockets%2F0e1cbc926773103d03774752e9108a00 +335 -0
  73. data/test/dummy/tmp/cache/assets/C66/FB0/sprockets%2F98a6552e0c72949d717178b5902e6f36 +71 -0
  74. data/test/dummy/tmp/cache/assets/C6D/F80/sprockets%2F44533615dbef3e810253094110825dac +62 -0
  75. data/test/dummy/tmp/cache/assets/C7A/910/sprockets%2F856f6b120c31d4622c49b3630219de68 +9069 -0
  76. data/test/dummy/tmp/cache/assets/C92/6A0/sprockets%2Fc5438348d868c777420d2e63fce56245 +98 -0
  77. data/test/dummy/tmp/cache/assets/C9C/A60/sprockets%2Fc6c3395667d18857f7f12369e53fa727 +350 -0
  78. data/test/dummy/tmp/cache/assets/CA7/430/sprockets%2F202cbe6f48604eb00549854f3053b58a +25 -0
  79. data/test/dummy/tmp/cache/assets/CB4/610/sprockets%2Ffeb1a7838d426857f0530993e420b60e +115 -0
  80. data/test/dummy/tmp/cache/assets/CE4/0D0/sprockets%2F439a9e8509403ac14ca356e5f2e9348b +7 -0
  81. data/test/dummy/tmp/cache/assets/CEB/DC0/sprockets%2F38536533e8e59a3fe0be483209c6d5c6 +352 -0
  82. data/test/dummy/tmp/cache/assets/CF6/900/sprockets%2F94575569edeb05737ebeaa60898940b6 +26 -0
  83. data/test/dummy/tmp/cache/assets/D07/4F0/sprockets%2Fe6091698b531dd271d5ac325b8b84ba0 +10 -0
  84. data/test/dummy/tmp/cache/assets/D19/BD0/sprockets%2F88636a6d051daca6365de6bd82096f48 +2445 -0
  85. data/test/dummy/tmp/cache/assets/D2B/3B0/sprockets%2F7de3b697dd206aa6eb292e301b140b60 +88 -0
  86. data/test/dummy/tmp/cache/assets/D39/410/sprockets%2Fa93af35d175ac7db006e63e91a0889b0 +42 -0
  87. data/test/dummy/tmp/cache/assets/D53/160/sprockets%2F8970dd07264d6eae78dd182d79df13c8 +303 -0
  88. data/test/dummy/tmp/cache/assets/D60/CE0/sprockets%2F06310f19d92bb4f40da80a37750ebdee +9 -0
  89. data/test/dummy/tmp/cache/assets/D65/620/sprockets%2F631e2801093d7a12aa6766bccaadfe88 +422 -0
  90. data/test/dummy/tmp/cache/assets/D7E/D20/sprockets%2Ff491cba4ec5176a691d9e5d7fc70892c +9052 -0
  91. data/test/dummy/tmp/cache/assets/D88/580/sprockets%2Ffef9b1c3b3b1b0316917a509cb1afb42 +439 -0
  92. data/test/dummy/tmp/cache/assets/D8E/B60/sprockets%2F1bc4810ecfe6a7b05c934eb3b0c2963a +9064 -0
  93. data/test/dummy/tmp/cache/assets/D99/D60/sprockets%2F29025313ddeaa1ff18cade1ed728949a +41 -0
  94. data/test/dummy/tmp/cache/assets/D9E/FD0/sprockets%2Ff8c955f36a2caa4039a66afc4c376e3a +0 -0
  95. data/test/dummy/tmp/cache/assets/DA5/1C0/sprockets%2Fec8cd61eddd7205e7c9c647f59413ac0 +371 -0
  96. data/test/dummy/tmp/cache/assets/DAF/6E0/sprockets%2F1b832fdf9fb97a8a7bcd2c907e652f47 +2386 -0
  97. data/test/dummy/tmp/cache/assets/DBC/650/sprockets%2Fd6da39f6f3f4a37c0db10cbc34ab0681 +67 -0
  98. data/test/dummy/tmp/cache/assets/DC2/150/sprockets%2F5cd685a35e3b593acade42a3b01def72 +8 -0
  99. data/test/dummy/tmp/cache/assets/DC7/530/sprockets%2Fea29d9af8aad9da0803062d3d7c06ac8 +373 -0
  100. data/test/dummy/tmp/cache/assets/DC9/2C0/sprockets%2Fbe1b3f07eb2f550c47c493a6f9a0de7b +333 -0
  101. data/test/dummy/tmp/cache/assets/DD6/820/sprockets%2Fb453f0fef899e0c6fe08aba14b94d09e +45 -0
  102. data/test/dummy/tmp/cache/assets/DD7/130/sprockets%2F6af271c6eec0698bc95224abf1ebf9f6 +390 -0
  103. data/test/dummy/tmp/cache/assets/E03/200/sprockets%2F8bd487cf65caa9fe453abd16be83e0a7 +70 -0
  104. data/test/dummy/tmp/cache/assets/E1D/680/sprockets%2Fc5c6b0ea20de8ef4d2f1eed00a35c93c +25 -0
  105. data/test/dummy/tmp/cache/assets/E49/440/sprockets%2Fbb92f156efb75bdda7bbacc04acb1425 +27 -0
  106. data/test/dummy/tmp/cache/assets/E59/430/sprockets%2Fb3073d96f7bcefcbdd3cdabe09a45a74 +286 -0
  107. data/test/dummy/tmp/cache/assets/E84/430/sprockets%2F61ffc0ed6338cebfdac2f1d3eaf0ae47 +9420 -0
  108. data/test/fixtures/sooner/admin/subscribers.yml +11 -0
  109. data/test/fixtures/sooner/subscribers.yml +7 -0
  110. data/test/functional/sooner/admin/subscribers_controller_test.rb +51 -0
  111. data/test/functional/sooner/subscribers_controller_test.rb +51 -0
  112. data/test/functional/sooner/subscribers_mailer_test.rb +14 -0
  113. data/test/integration/navigation_test.rb +10 -0
  114. data/test/sooner_test.rb +7 -0
  115. data/test/test_helper.rb +10 -0
  116. data/test/unit/helpers/sooner/admin/subscribers_helper_test.rb +6 -0
  117. data/test/unit/helpers/sooner/subscribers_helper_test.rb +6 -0
  118. data/test/unit/sooner/admin/subscriber_test.rb +9 -0
  119. data/test/unit/sooner/subscriber_test.rb +9 -0
  120. metadata +252 -53
  121. data/Gemfile +0 -4
  122. data/lib/sooner/email_format_validator.rb +0 -9
  123. data/lib/sooner/rails.rb +0 -5
@@ -0,0 +1,286 @@
1
+ o: ActiveSupport::Cache::Entry :@compressedF:@expires_in0:@created_atf1320224789.7169316: @value{ I" length:EFi3I" digest;
2
+ F"%a6be690938da0b8e798830d8eeaa809aI" source;
3
+ FI"3/*! Respond.js v1.0.1pre: min/max-width media query polyfill. (c) Scott Jehl. MIT/GPLv2 Lic. j.mp/respondjs */
4
+
5
+ (function( win, mqSupported ){
6
+ //exposed namespace
7
+ win.respond = {};
8
+
9
+ //define update even in native-mq-supporting browsers, to avoid errors
10
+ respond.update = function(){};
11
+
12
+ //expose media query support flag for external use
13
+ respond.mediaQueriesSupported = mqSupported;
14
+
15
+ //if media queries are supported, exit here
16
+ if( mqSupported ){ return; }
17
+
18
+ //define vars
19
+ var doc = win.document,
20
+ docElem = doc.documentElement,
21
+ mediastyles = [],
22
+ rules = [],
23
+ appendedEls = [],
24
+ parsedSheets = {},
25
+ resizeThrottle = 30,
26
+ head = doc.getElementsByTagName( "head" )[0] || docElem,
27
+ links = head.getElementsByTagName( "link" ),
28
+ requestQueue = [],
29
+
30
+ //loop stylesheets, send text content to translate
31
+ ripCSS = function(){
32
+ var sheets = links,
33
+ sl = sheets.length,
34
+ i = 0,
35
+ //vars for loop:
36
+ sheet, href, media, isCSS;
37
+
38
+ for( ; i < sl; i++ ){
39
+ sheet = sheets[ i ],
40
+ href = sheet.href,
41
+ media = sheet.media,
42
+ isCSS = sheet.rel && sheet.rel.toLowerCase() === "stylesheet";
43
+
44
+ //only links plz and prevent re-parsing
45
+ if( !!href && isCSS && !parsedSheets[ href ] ){
46
+ // selectivizr exposes css through the rawCssText expando
47
+ if (sheet.styleSheet && sheet.styleSheet.rawCssText) {
48
+ translate( sheet.styleSheet.rawCssText, href, media );
49
+ parsedSheets[ href ] = true;
50
+ } else {
51
+ if( !/^([a-zA-Z]+?:(\/\/)?)/.test( href )
52
+ || href.replace( RegExp.$1, "" ).split( "/" )[0] === win.location.host ){
53
+ requestQueue.push( {
54
+ href: href,
55
+ media: media
56
+ } );
57
+ }
58
+ }
59
+ }
60
+ }
61
+ makeRequests();
62
+
63
+ },
64
+
65
+ //recurse through request queue, get css text
66
+ makeRequests = function(){
67
+ if( requestQueue.length ){
68
+ var thisRequest = requestQueue.shift();
69
+
70
+ ajax( thisRequest.href, function( styles ){
71
+ translate( styles, thisRequest.href, thisRequest.media );
72
+ parsedSheets[ thisRequest.href ] = true;
73
+ makeRequests();
74
+ } );
75
+ }
76
+ },
77
+
78
+ //find media blocks in css text, convert to style blocks
79
+ translate = function( styles, href, media ){
80
+ var qs = styles.match( /@media[^\{]+\{([^\{\}]+\{[^\}\{]+\})+/gi ),
81
+ ql = qs && qs.length || 0,
82
+ //try to get CSS path
83
+ href = href.substring( 0, href.lastIndexOf( "/" )),
84
+ repUrls = function( css ){
85
+ return css.replace( /(url\()['"]?([^\/\)'"][^:\)'"]+)['"]?(\))/g, "$1" + href + "$2$3" );
86
+ },
87
+ useMedia = !ql && media,
88
+ //vars used in loop
89
+ i = 0,
90
+ j, fullq, thisq, eachq, eql;
91
+
92
+ //if path exists, tack on trailing slash
93
+ if( href.length ){ href += "/"; }
94
+
95
+ //if no internal queries exist, but media attr does, use that
96
+ //note: this currently lacks support for situations where a media attr is specified on a link AND
97
+ //its associated stylesheet has internal CSS media queries.
98
+ //In those cases, the media attribute will currently be ignored.
99
+ if( useMedia ){
100
+ ql = 1;
101
+ }
102
+
103
+
104
+ for( ; i < ql; i++ ){
105
+ j = 0;
106
+
107
+ //media attr
108
+ if( useMedia ){
109
+ fullq = media;
110
+ rules.push( repUrls( styles ) );
111
+ }
112
+ //parse for styles
113
+ else{
114
+ fullq = qs[ i ].match( /@media ([^\{]+)\{([\S\s]+?)$/ ) && RegExp.$1;
115
+ rules.push( RegExp.$2 && repUrls( RegExp.$2 ) );
116
+ }
117
+
118
+ eachq = fullq.split( "," );
119
+ eql = eachq.length;
120
+
121
+
122
+ for( ; j < eql; j++ ){
123
+ thisq = eachq[ j ];
124
+ mediastyles.push( {
125
+ media : thisq.match( /(only\s+)?([a-zA-Z]+)(\sand)?/ ) && RegExp.$2,
126
+ rules : rules.length - 1,
127
+ minw : thisq.match( /\(min\-width:[\s]*([\s]*[0-9]+)px[\s]*\)/ ) && parseFloat( RegExp.$1 ),
128
+ maxw : thisq.match( /\(max\-width:[\s]*([\s]*[0-9]+)px[\s]*\)/ ) && parseFloat( RegExp.$1 )
129
+ } );
130
+ }
131
+ }
132
+
133
+ applyMedia();
134
+ },
135
+
136
+ lastCall,
137
+
138
+ resizeDefer,
139
+
140
+ //enable/disable styles
141
+ applyMedia = function( fromResize ){
142
+ var name = "clientWidth",
143
+ docElemProp = docElem[ name ],
144
+ currWidth = doc.compatMode === "CSS1Compat" && docElemProp || doc.body[ name ] || docElemProp,
145
+ styleBlocks = {},
146
+ dFrag = doc.createDocumentFragment(),
147
+ lastLink = links[ links.length-1 ],
148
+ now = (new Date()).getTime();
149
+
150
+ //throttle resize calls
151
+ if( fromResize && lastCall && now - lastCall < resizeThrottle ){
152
+ clearTimeout( resizeDefer );
153
+ resizeDefer = setTimeout( applyMedia, resizeThrottle );
154
+ return;
155
+ }
156
+ else {
157
+ lastCall = now;
158
+ }
159
+
160
+ for( var i in mediastyles ){
161
+ var thisstyle = mediastyles[ i ];
162
+ if( !thisstyle.minw && !thisstyle.maxw ||
163
+ ( !thisstyle.minw || thisstyle.minw && currWidth >= thisstyle.minw ) &&
164
+ (!thisstyle.maxw || thisstyle.maxw && currWidth <= thisstyle.maxw ) ){
165
+ if( !styleBlocks[ thisstyle.media ] ){
166
+ styleBlocks[ thisstyle.media ] = [];
167
+ }
168
+ styleBlocks[ thisstyle.media ].push( rules[ thisstyle.rules ] );
169
+ }
170
+ }
171
+
172
+ //remove any existing respond style element(s)
173
+ for( var i in appendedEls ){
174
+ if( appendedEls[ i ] && appendedEls[ i ].parentNode === head ){
175
+ head.removeChild( appendedEls[ i ] );
176
+ }
177
+ }
178
+
179
+ //inject active styles, grouped by media type
180
+ for( var i in styleBlocks ){
181
+ var ss = doc.createElement( "style" ),
182
+ css = styleBlocks[ i ].join( "\n" );
183
+
184
+ ss.type = "text/css";
185
+ ss.media = i;
186
+
187
+ if ( ss.styleSheet ){
188
+ ss.styleSheet.cssText = css;
189
+ }
190
+ else {
191
+ ss.appendChild( doc.createTextNode( css ) );
192
+ }
193
+ dFrag.appendChild( ss );
194
+ appendedEls.push( ss );
195
+ }
196
+
197
+ //append to DOM at once
198
+ head.insertBefore( dFrag, lastLink.nextSibling );
199
+ },
200
+ //tweaked Ajax functions from Quirksmode
201
+ ajax = function( url, callback ) {
202
+ var req = xmlHttp();
203
+ if (!req){
204
+ return;
205
+ }
206
+ req.open( "GET", url, true );
207
+ req.onreadystatechange = function () {
208
+ if ( req.readyState != 4 || req.status != 200 && req.status != 304 ){
209
+ return;
210
+ }
211
+ callback( req.responseText );
212
+ }
213
+ if ( req.readyState == 4 ){
214
+ return;
215
+ }
216
+ req.send( null );
217
+ },
218
+ //define ajax obj
219
+ xmlHttp = (function() {
220
+ var xmlhttpmethod = false;
221
+ try {
222
+ xmlhttpmethod = new XMLHttpRequest();
223
+ }
224
+ catch( e ){
225
+ xmlhttpmethod = new ActiveXObject( "Microsoft.XMLHTTP" );
226
+ }
227
+ return function(){
228
+ return xmlhttpmethod;
229
+ };
230
+ })();
231
+
232
+ //translate CSS
233
+ ripCSS();
234
+
235
+ //expose update for re-running respond later on
236
+ respond.update = ripCSS;
237
+
238
+ //adjust on resize
239
+ function callMedia(){
240
+ applyMedia( true );
241
+ }
242
+ if( win.addEventListener ){
243
+ win.addEventListener( "resize", callMedia, false );
244
+ }
245
+ else if( win.attachEvent ){
246
+ win.attachEvent( "onresize", callMedia );
247
+ }
248
+ })(
249
+ this,
250
+ (function( win ){
251
+
252
+ //for speed, flag browsers with window.matchMedia support and IE 9 as supported
253
+ if( win.matchMedia ){ return true; }
254
+
255
+ var bool,
256
+ doc = document,
257
+ docElem = doc.documentElement,
258
+ refNode = docElem.firstElementChild || docElem.firstChild,
259
+ // fakeBody required for <FF4 when executed in <head>
260
+ fakeUsed = !doc.body,
261
+ fakeBody = doc.body || doc.createElement( "body" ),
262
+ div = doc.createElement( "div" ),
263
+ q = "only all";
264
+
265
+ div.id = "mq-test-1";
266
+ div.style.cssText = "position:absolute;top:-99em";
267
+ fakeBody.appendChild( div );
268
+
269
+ div.innerHTML = '_<style media="'+q+'"> #mq-test-1 { width: 9px; }</style>';
270
+ if( fakeUsed ){
271
+ docElem.insertBefore( fakeBody, refNode );
272
+ }
273
+ div.removeChild( div.firstChild );
274
+ bool = div.offsetWidth == 9;
275
+ if( fakeUsed ){
276
+ docElem.removeChild( fakeBody );
277
+ }
278
+ else{
279
+ fakeBody.removeChild( div );
280
+ }
281
+ return bool;
282
+ })( this )
283
+ );
284
+ ;
285
+ FI"
286
+ F"%d5b5f1bf9c4a2a9a05a4a792c814e4e9