redditor 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (166) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +27 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +8 -0
  5. data/Gemfile +23 -0
  6. data/Guardfile +24 -0
  7. data/MIT-LICENSE +20 -0
  8. data/README.md +16 -0
  9. data/Rakefile +23 -0
  10. data/app/assets/images/redditor/.keep +0 -0
  11. data/app/assets/images/redditor/add_photo.png +0 -0
  12. data/app/assets/images/redditor/add_photo_big.png +0 -0
  13. data/app/assets/images/redditor/add_slider.png +0 -0
  14. data/app/assets/images/redditor/add_slider_big.png +0 -0
  15. data/app/assets/images/redditor/add_txt.png +0 -0
  16. data/app/assets/images/redditor/add_txt_big.png +0 -0
  17. data/app/assets/images/redditor/add_video.png +0 -0
  18. data/app/assets/images/redditor/add_video_big.png +0 -0
  19. data/app/assets/images/redditor/destroy_block_text.png +0 -0
  20. data/app/assets/images/redditor/move_handler.png +0 -0
  21. data/app/assets/images/redditor/no_format_text.png +0 -0
  22. data/app/assets/images/redditor/trash.png +0 -0
  23. data/app/assets/javascripts/fileapi/FileAPI.exif.js +59 -0
  24. data/app/assets/javascripts/fileapi/FileAPI.flash.image.swf +0 -0
  25. data/app/assets/javascripts/fileapi/FileAPI.flash.swf +0 -0
  26. data/app/assets/javascripts/fileapi/FileAPI.id3.js +67 -0
  27. data/app/assets/javascripts/fileapi/FileAPI.min.js +73 -0
  28. data/app/assets/javascripts/fileapi/fileapi.js.coffee.erb +12 -0
  29. data/app/assets/javascripts/fileapi/tmpl.js +35 -0
  30. data/app/assets/javascripts/fileapi/uploader.coffee +139 -0
  31. data/app/assets/javascripts/jquery-ui.min.js +12 -0
  32. data/app/assets/javascripts/redditor/application.js +14 -0
  33. data/app/assets/javascripts/redditor/fileapi/FileAPI.exif.js +59 -0
  34. data/app/assets/javascripts/redditor/fileapi/FileAPI.flash.image.swf +0 -0
  35. data/app/assets/javascripts/redditor/fileapi/FileAPI.flash.swf +0 -0
  36. data/app/assets/javascripts/redditor/fileapi/FileAPI.id3.js +67 -0
  37. data/app/assets/javascripts/redditor/fileapi/FileAPI.min.js +72 -0
  38. data/app/assets/javascripts/redditor/fileapi/README.md +724 -0
  39. data/app/assets/javascripts/redditor/fileapi/config.js.coffee.erb +5 -0
  40. data/app/assets/javascripts/redditor/fileapi/crossdomain.xml +19 -0
  41. data/app/assets/javascripts/redditor/fileapi/example.userpic.html +212 -0
  42. data/app/assets/javascripts/redditor/fileapi/index.html +548 -0
  43. data/app/assets/javascripts/redditor/fileapi/mailru.js +6 -0
  44. data/app/assets/javascripts/redditor/fileapi/mailru_front.js.coffee +143 -0
  45. data/app/assets/javascripts/redditor/fileapi/tmpl.js +35 -0
  46. data/app/assets/javascripts/redditor/fileapi/uploader.coffee +139 -0
  47. data/app/assets/javascripts/redditor/redditor.coffee +148 -0
  48. data/app/assets/stylesheets/redditor/application.css.scss +47 -0
  49. data/app/assets/stylesheets/redditor/fileapi/fileapi.css.scss +174 -0
  50. data/app/assets/stylesheets/redditor/fileapi/fileapi_front.css.scss +175 -0
  51. data/app/assets/stylesheets/redditor/redditor.css.scss +108 -0
  52. data/app/controllers/redditor/admin/base_controller.rb +18 -0
  53. data/app/controllers/redditor/admin/image_blocks_controller.rb +37 -0
  54. data/app/controllers/redditor/admin/images_controller.rb +33 -0
  55. data/app/controllers/redditor/admin/pages_controller.rb +15 -0
  56. data/app/controllers/redditor/admin/slider_blocks_controller.rb +32 -0
  57. data/app/controllers/redditor/admin/text_blocks_controller.rb +31 -0
  58. data/app/controllers/redditor/admin/video_blocks_controller.rb +31 -0
  59. data/app/controllers/redditor/application_controller.rb +4 -0
  60. data/app/helpers/redditor/application_helper.rb +4 -0
  61. data/app/helpers/redditor/fileapi_helper.rb +17 -0
  62. data/app/helpers/redditor/pages_helper.rb +24 -0
  63. data/app/models/redditor/content_block.rb +24 -0
  64. data/app/models/redditor/image.rb +29 -0
  65. data/app/models/redditor/page.rb +28 -0
  66. data/app/models/redditor/slider_block.rb +17 -0
  67. data/app/models/redditor/text_block.rb +20 -0
  68. data/app/models/redditor/video_block.rb +27 -0
  69. data/app/uploaders/redditor_uploader.rb +57 -0
  70. data/app/views/layouts/redditor/application.html.erb +15 -0
  71. data/app/views/redditor/admin/pages/_content_block.haml +16 -0
  72. data/app/views/redditor/admin/pages/_fileapi.erb +199 -0
  73. data/app/views/redditor/admin/pages/_image.haml +18 -0
  74. data/app/views/redditor/admin/pages/_page.haml +13 -0
  75. data/app/views/redditor/admin/pages/_slider_block.haml +16 -0
  76. data/app/views/redditor/admin/pages/_slider_block_image.haml +3 -0
  77. data/app/views/redditor/admin/pages/_text_block.haml +5 -0
  78. data/app/views/redditor/admin/pages/_validate.haml +4 -0
  79. data/app/views/redditor/admin/pages/_video_block.haml +19 -0
  80. data/app/views/redditor/admin/pages/_wrap_dd.haml +1 -0
  81. data/app/views/redditor/admin/pages/_wrapper.haml +3 -0
  82. data/app/views/redditor/admin/pages/new.js.coffee +7 -0
  83. data/app/views/redditor/admin/pages/new.js.erb +7 -0
  84. data/app/views/redditor/admin/pages/slider_block_image.js.coffee +2 -0
  85. data/app/views/redditor/admin/pages/wrapper.js.coffee +6 -0
  86. data/app/views/redditor/pages/_page.html.haml +1 -0
  87. data/app/views/redditor/slider_blocks/_slider_block.html.haml +2 -0
  88. data/app/views/redditor/slider_blocks/_slider_block_image.html.erb +3 -0
  89. data/app/views/redditor/text_blocks/_text_block.html.haml +1 -0
  90. data/app/views/redditor/video_blocks/_video_block.html.haml +2 -0
  91. data/bin/rails +8 -0
  92. data/config/locales/redditor.en.yml +20 -0
  93. data/config/locales/redditor.ru.yml +20 -0
  94. data/config/routes.rb +17 -0
  95. data/db/migrate/20130916155124_create_redditor_images.rb +15 -0
  96. data/db/migrate/20130916155156_create_redditor_pages.rb +12 -0
  97. data/db/migrate/20130916155219_create_redditor_slider_blocks.rb +11 -0
  98. data/db/migrate/20130916155239_create_redditor_text_blocks.rb +12 -0
  99. data/db/migrate/20130916155301_create_redditor_video_blocks.rb +14 -0
  100. data/lib/generators/redditor/views/views_generator.rb +17 -0
  101. data/lib/redditor/engine.rb +12 -0
  102. data/lib/redditor/has_redditor.rb +17 -0
  103. data/lib/redditor/version.rb +3 -0
  104. data/lib/redditor.rb +9 -0
  105. data/lib/tasks/redditor_tasks.rake +4 -0
  106. data/redditor.gemspec +38 -0
  107. data/spec/dummy/.rspec +1 -0
  108. data/spec/dummy/README.rdoc +28 -0
  109. data/spec/dummy/Rakefile +6 -0
  110. data/spec/dummy/app/assets/images/.keep +0 -0
  111. data/spec/dummy/app/assets/javascripts/application.js +17 -0
  112. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  113. data/spec/dummy/app/controllers/admin/articles_controller.rb +23 -0
  114. data/spec/dummy/app/controllers/admin/base_controller.rb +6 -0
  115. data/spec/dummy/app/controllers/application_controller.rb +5 -0
  116. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  117. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  118. data/spec/dummy/app/mailers/.keep +0 -0
  119. data/spec/dummy/app/models/.keep +0 -0
  120. data/spec/dummy/app/models/article.rb +7 -0
  121. data/spec/dummy/app/models/concerns/.keep +0 -0
  122. data/spec/dummy/app/views/admin/articles/edit.html.haml +15 -0
  123. data/spec/dummy/app/views/articles/show.html.haml +2 -0
  124. data/spec/dummy/app/views/layouts/application.html.erb +15 -0
  125. data/spec/dummy/bin/bundle +3 -0
  126. data/spec/dummy/bin/rails +4 -0
  127. data/spec/dummy/bin/rake +4 -0
  128. data/spec/dummy/config/application.rb +31 -0
  129. data/spec/dummy/config/boot.rb +5 -0
  130. data/spec/dummy/config/database.yml +25 -0
  131. data/spec/dummy/config/environment.rb +5 -0
  132. data/spec/dummy/config/environments/development.rb +29 -0
  133. data/spec/dummy/config/environments/production.rb +80 -0
  134. data/spec/dummy/config/environments/test.rb +36 -0
  135. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  136. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  137. data/spec/dummy/config/initializers/inflections.rb +16 -0
  138. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  139. data/spec/dummy/config/initializers/secret_token.rb +12 -0
  140. data/spec/dummy/config/initializers/session_store.rb +3 -0
  141. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  142. data/spec/dummy/config/locales/en.yml +23 -0
  143. data/spec/dummy/config/routes.rb +10 -0
  144. data/spec/dummy/config.ru +4 -0
  145. data/spec/dummy/db/migrate/20130908123351_create_articles.rb +9 -0
  146. data/spec/dummy/db/schema.rb +76 -0
  147. data/spec/dummy/lib/assets/.keep +0 -0
  148. data/spec/dummy/log/.keep +0 -0
  149. data/spec/dummy/public/404.html +58 -0
  150. data/spec/dummy/public/422.html +58 -0
  151. data/spec/dummy/public/500.html +57 -0
  152. data/spec/dummy/public/favicon.ico +0 -0
  153. data/spec/factories/articles_factory.rb +27 -0
  154. data/spec/factories/redditor/images_factory.rb +9 -0
  155. data/spec/factories/redditor/pages_factory.rb +37 -0
  156. data/spec/factories/redditor/sliders_factory.rb +9 -0
  157. data/spec/factories/redditor/texts_factory.rb +5 -0
  158. data/spec/factories/redditor/videos_factories.rb +7 -0
  159. data/spec/features/text_spec.rb +52 -0
  160. data/spec/features/video_spec.rb +52 -0
  161. data/spec/fixtures/test.jpg +0 -0
  162. data/spec/generators/views_generator_spec.rb +20 -0
  163. data/spec/models/article_spec.rb +40 -0
  164. data/spec/spec_helper.rb +67 -0
  165. data/spec/views/article/show_spec.rb +22 -0
  166. metadata +480 -0
@@ -0,0 +1,548 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
6
+
7
+ <title>FileAPI :: TEST</title>
8
+
9
+ <meta name="viewport" content="user-scalable=no, width=400, initial-scale=0.8, maximum-scale=0.8" />
10
+ <meta name="apple-mobile-web-app-capable" content="yes" />
11
+ <meta name="apple-mobile-web-app-status-bar-style" content="yes" />
12
+ <meta name="format-detection" content="email=no" />
13
+ <meta name="HandheldFriendly" content="true" />
14
+
15
+ <script src="//yandex.st/jquery/1.8.2/jquery.min.js"></script>
16
+ <script>if( !window.jQuery )document.write('<script src="/js/jquery.dev.js"><'+'/script>');</script>
17
+
18
+ <script>var FileAPI = { debug: false, pingUrl: false }</script>
19
+ <script src="./FileAPI.min.js"></script>
20
+ <script src="./FileAPI.id3.js"></script>
21
+ <script src="./FileAPI.exif.js"></script>
22
+
23
+ <script>
24
+ // Simple JavaScript Templating
25
+ // John Resig - http://ejohn.org/ - MIT Licensed
26
+ (function (){
27
+ var cache = {};
28
+
29
+ this.tmpl = function tmpl(str, data){
30
+ // Figure out if we're getting a template, or if we need to
31
+ // load the template - and be sure to cache the result.
32
+ var fn = !/\W/.test(str) ?
33
+ cache[str] = cache[str] ||
34
+ tmpl(document.getElementById(str).innerHTML) :
35
+
36
+ // Generate a reusable function that will serve as a template
37
+ // generator (and which will be cached).
38
+ new Function("obj",
39
+ "var p=[],print=function(){p.push.apply(p,arguments);};" +
40
+
41
+ // Introduce the data as local variables using with(){}
42
+ "with(obj){p.push('" +
43
+
44
+ // Convert the template into pure JavaScript
45
+ str
46
+ .replace(/[\r\t\n]/g, " ")
47
+ .split("<%").join("\t")
48
+ .replace(/((^|%>)[^\t]*)'/g, "$1\r")
49
+ .replace(/\t=(.*?)%>/g, "',$1,'")
50
+ .split("\t").join("');")
51
+ .split("%>").join("p.push('")
52
+ .split("\r").join("\\'")
53
+ + "');}return p.join('');");
54
+
55
+ // Provide some basic currying to the user
56
+ return data ? fn(data) : fn;
57
+ };
58
+ })();
59
+ </script>
60
+
61
+ <style>
62
+ body {
63
+ font-size: 15px;
64
+ font-family: "Helvetica Neue";
65
+ }
66
+
67
+ .b-button {
68
+ display: inline-block;
69
+ *display: inline;
70
+ *zoom: 1;
71
+ position: relative;
72
+ overflow: hidden;
73
+ cursor: pointer;
74
+ padding: 4px 15px;
75
+ vertical-align: middle;
76
+ border: 1px solid #ccc;
77
+ border-radius: 3px;
78
+ background-color: #f5f5f5;
79
+ background: -moz-linear-gradient(top, #fff 0%, #f5f5f5 49%, #ececec 50%, #eee 100%);
80
+ background: -webkit-linear-gradient(top, #fff 0%,#f5f5f5 49%,#ececec 50%,#eee 100%);
81
+ background: -o-linear-gradient(top, #fff 0%,#f5f5f5 49%,#ececec 50%,#eee 100%);
82
+ background: linear-gradient(to bottom, #fff 0%,#f5f5f5 49%,#ececec 50%,#eee 100%);
83
+ -webkit-user-select: none;
84
+ -moz-user-select: none;
85
+ user-select: none;
86
+ }
87
+ .b-button_hover {
88
+ border-color: #fa0;
89
+ box-shadow: 0 0 2px #fa0;
90
+ }
91
+
92
+ .b-button__text {
93
+ }
94
+
95
+ .b-button__input {
96
+ cursor: pointer;
97
+ opacity: 0;
98
+ filter:progid:DXImageTransform.Microsoft.Alpha(opacity=0);
99
+ top: -10px;
100
+ right: -40px;
101
+ font-size: 50px;
102
+ position: absolute;
103
+ }
104
+
105
+
106
+ #preview {
107
+ max-width: 600px;
108
+ box-shadow: 0 1px 3px rgba(0,0,0,.4);
109
+ border-radius: 3px;
110
+ }
111
+ .b-file {
112
+ height: 40px;
113
+ padding: 5px;
114
+ position: relative;
115
+ overflow: hidden;
116
+ border-radius: 3px;
117
+ background-color: #fcfcfc;
118
+ background: -webkit-linear-gradient(top, #fcfcfc 0%, #f6f6f6 100%);
119
+ background: -moz-linear-gradient(top, #fcfcfc 0%, #f6f6f6 100%);
120
+ background: -o-linear-gradient(top, #fcfcfc 0%, #f6f6f6 100%);
121
+ background: linear-gradient(to bottom, #fcfcfc 0%, #f6f6f6 100%);
122
+ clear: both;
123
+ }
124
+ .b-file__left {
125
+ float: left;
126
+ margin: 1px 0 0 2px;
127
+ line-height: 0;
128
+ }
129
+ .b-file__left_border {
130
+ border: 2px solid #fff;
131
+ border-radius: 4px;
132
+ }
133
+
134
+ .b-file__right {
135
+ margin-left: 45px;
136
+ }
137
+
138
+ .b-file__name {
139
+ color: #36c;
140
+ cursor: pointer;
141
+ border-bottom: 1px dotted #36c;
142
+ text-decoration: none;
143
+ }
144
+ .b-file__name:hover {
145
+ color: #f00;
146
+ border-bottom-color: #f00;
147
+ }
148
+
149
+ .b-file__info {
150
+ color: #666;
151
+ position: absolute;
152
+ font-size: 12px;
153
+ margin-top: 3px;
154
+ }
155
+
156
+ .b-file__bar {
157
+ padding-top: 4px;
158
+ }
159
+
160
+ .b-file__error {
161
+ color: #c00;
162
+ }
163
+ .b-file__done {
164
+ color: #458383;
165
+ }
166
+ .b-file__abort {
167
+ top: 10px;
168
+ right: 20px;
169
+ width: 15px;
170
+ height: 15px;
171
+ position: absolute;
172
+ color: #c00;
173
+ cursor: pointer;
174
+ font-size: 20px;
175
+ display: none;
176
+ }
177
+ .b-file_upload .b-file__abort { display: block; }
178
+
179
+ .b-progress {
180
+ width: 200px;
181
+ height: 10px;
182
+ border: 2px solid #E2E4E2;
183
+ border-radius: 10px;
184
+ box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
185
+ background-color: #d3d3d3;
186
+ position: relative;
187
+ }
188
+ .b-progress__bar {
189
+ width: 0;
190
+ height: 10px;
191
+ border-radius: 10px;
192
+ background-color: #2D9DD7;
193
+ background: -webkit-linear-gradient(top, #2D9DD7 0%, #1C81C7 100%); /* FF3.6+ */
194
+ background: -moz-linear-gradient(top, #2D9DD7 0%, #1C81C7 100%); /* FF3.6+ */
195
+ background: linear-gradient(to bottom, #2D9DD7 0%, #1C81C7 100%); /* FF3.6+ */
196
+ -webkit-transition: width .5s ease-out;
197
+ -moz-transition: width .5s ease-out;
198
+ -ms-transition: width .5s ease-out;
199
+ transition: width .5s ease-out;
200
+ }
201
+
202
+ .b-dropzone,
203
+ .b-dropzone__bg {
204
+ top: 0;
205
+ left: 0;
206
+ right: 0;
207
+ bottom: 0;
208
+ z-index: 30000;
209
+ position: absolute;
210
+ }
211
+ .b-dropzone__bg {
212
+ opacity: .2;
213
+ background-color: #2D9DD7
214
+ }
215
+ .b-dropzone__txt {
216
+ color: #1C81C7;
217
+ text-shadow: 0 2px 1px #113C53;
218
+ font-size: 400%;
219
+ font-weight: bold;
220
+ text-align: center;
221
+ width: 500px;
222
+ top: 50%;
223
+ left: 50%;
224
+ margin: -100px 0 0 -250px;
225
+ z-index: 30001;
226
+ position: absolute;
227
+ }
228
+
229
+ .b-layer {
230
+ border: 3px solid #fff;
231
+ border-radius: 5px;
232
+ box-shadow: 0 1px 30px #000;
233
+ background-color: #f3f3f3;
234
+ top: 50px;
235
+ left: 50%;
236
+ z-index: 30002;
237
+ position: absolute;
238
+ margin-left: -150px;
239
+ margin-bottom: 100px;
240
+ }
241
+ .b-layer__h1 {
242
+ color: #fff;
243
+ padding: 10px 10px;
244
+ width: 300px;
245
+ overflow: hidden;
246
+ background-color: #2D9DD7;
247
+ }
248
+ .b-layer__img {
249
+ padding: 5px 10px;
250
+ text-align: center;
251
+ border-top: 2px solid #fff;
252
+ }
253
+ .b-layer__info {
254
+ padding: 2px 15px;
255
+ border-top: 2px solid #fff;
256
+ }
257
+ .b-layer__info div {
258
+ width: 280px;
259
+ overflow: hidden;
260
+ white-space: nowrap;
261
+ }
262
+
263
+
264
+ .examples {
265
+ left: 0;
266
+ right: 0;
267
+ bottom: 0;
268
+ position: fixed;
269
+ box-shadow: 0 0 5px rgba(0,0,0,.65);
270
+ background-color: #fff;
271
+ }
272
+ .examples__inner {
273
+ padding: 5px 10px;
274
+ }
275
+ </style>
276
+
277
+ </head>
278
+ <body>
279
+ <div class="examples">
280
+ <div class="examples__inner">
281
+ <a href="./example.userpic.html">user pic</a>
282
+ </div>
283
+ </div>
284
+
285
+ <div id="drop-zone" class="b-dropzone" style="display: none">
286
+ <div class="b-dropzone__bg"></div>
287
+ <div class="b-dropzone__txt">Drop files there</div>
288
+ </div>
289
+
290
+ <div id="oooops" style="display: none; margin: 10px; padding: 10px; border: 2px solid #f60; border-radius: 4px;">
291
+ Увы, ваш браузер не поддерживает html5 и flash,
292
+ поэтому смотреть тут нечего, а iframe не даёт всей красоты :]
293
+ </div>
294
+
295
+ <div id="buttons-panel">
296
+ <div class="b-button js-fileapi-wrapper">
297
+ <div class="b-button__text">Upload one file</div>
298
+ <input name="files" class="b-button__input" type="file" />
299
+ </div>
300
+
301
+ <div class="b-button js-fileapi-wrapper">
302
+ <div class="b-button__text">Multiple</div>
303
+ <input name="files" class="b-button__input" type="file" multiple />
304
+ </div>
305
+
306
+ <div class="b-button js-fileapi-wrapper">
307
+ <div class="b-button__text">jpg, jpeg & gif</div>
308
+ <input name="files" class="b-button__input" type="file" accept=".jpg,.jpeg,.gif" multiple />
309
+ </div>
310
+
311
+ <span id="drag-n-drop" style="display: none; padding: 0 30px">
312
+ or &nbsp; &nbsp; drag'n'drop
313
+ </span>
314
+ </div>
315
+
316
+ <div id="preview" style="margin-top: 30px"></div>
317
+
318
+ <script id="b-file-ejs" type="text/ejs">
319
+ <div id="file-<%=FileAPI.uid(file)%>" class="js-file b-file b-file_<%=file.type.split('/')[0]%>">
320
+ <div class="js-left b-file__left">
321
+ <img src="<%=icon[file.type.split('/')[0]]||icon.def%>" width="32" height="32" style="margin: 2px 0 0 3px"/>
322
+ </div>
323
+ <div class="b-file__right">
324
+ <div><a class="js-name b-file__name"><%=file.name%></a></div>
325
+ <div class="js-info b-file__info">size: <%=(file.size/FileAPI.KB).toFixed(2)%> KB</div>
326
+ <div class="js-progress b-file__bar" style="display: none">
327
+ <div class="b-progress"><div class="js-bar b-progress__bar"></div></div>
328
+ </div>
329
+ </div>
330
+ <i class="js-abort b-file__abort" title="abort">&times;</i>
331
+ </div>
332
+ </script>
333
+
334
+ <script id="b-layer-ejs" type="text/ejs">
335
+ <div class="b-layer">
336
+ <div class="b-layer__h1"><%=file.name%></div>
337
+ <div class="js-img b-layer__img"></div>
338
+ <div class="b-layer__info">
339
+ <%
340
+ FileAPI.each(info, function(val, key){
341
+ if( Object.prototype.toString.call(val) == '[object Object]' ){
342
+ var sub = '';
343
+ FileAPI.each(val, function (val, key){ sub += '<div>'+key+': '+val+'</div>'; });
344
+ if( sub ){
345
+ %><%=key%><div style="margin: 0 0 5px 20px;"><%=sub%></div><%
346
+ }
347
+ } else {
348
+ %>
349
+ <div><%=key%>: <%=val%></div>
350
+ <%
351
+ }
352
+ });
353
+ %>
354
+ </div>
355
+ </div>
356
+ </script>
357
+
358
+
359
+ <script type="text/javascript">
360
+ jQuery(function ($){
361
+ if( !(FileAPI.support.cors || FileAPI.support.flash) ){
362
+ $('#oooops').show();
363
+ $('#buttons-panel').hide();
364
+ }
365
+
366
+ $(document).on('mouseenter mouseleave', '.b-button', function (evt){
367
+ $(evt.currentTarget).toggleClass('b-button_hover', evt.type == 'mouseenter');
368
+ });
369
+
370
+
371
+ if( FileAPI.support.dnd ){
372
+ $('#drag-n-drop').show();
373
+ $(document).dnd(function (over){
374
+ $('#drop-zone').toggle(over);
375
+ }, function (files){
376
+ onFiles(files);
377
+ });
378
+ }
379
+
380
+
381
+ $('input[type="file"]').on('change', function (evt){
382
+ var files = FileAPI.getFiles(evt);
383
+ onFiles(files);
384
+ FileAPI.reset(evt.currentTarget);
385
+ });
386
+
387
+
388
+ var FU = {
389
+ icon: {
390
+ def: '//cdn1.iconfinder.com/data/icons/CrystalClear/32x32/mimetypes/unknown.png'
391
+ , image: '//cdn1.iconfinder.com/data/icons/humano2/32x32/apps/synfig_icon.png'
392
+ , audio: '//cdn1.iconfinder.com/data/icons/august/PNG/Music.png'
393
+ , video: '//cdn1.iconfinder.com/data/icons/df_On_Stage_Icon_Set/128/Video.png'
394
+ },
395
+
396
+ files: [],
397
+ index: 0,
398
+ active: false,
399
+
400
+ add: function (file){
401
+ FU.files.push(file);
402
+
403
+ if( /^image/.test(file.type) ){
404
+ FileAPI.Image(file).preview(35).rotate('auto').get(function (err, img){
405
+ if( !err ){
406
+ FU._getEl(file, '.js-left')
407
+ .addClass('b-file__left_border')
408
+ .html(img)
409
+ ;
410
+ }
411
+ });
412
+ }
413
+ },
414
+
415
+ getFileById: function (id){
416
+ var i = FU.files.length;
417
+ while( i-- ){
418
+ if( FileAPI.uid(FU.files[i]) == id ){
419
+ return FU.files[i];
420
+ }
421
+ }
422
+ },
423
+
424
+ showLayer: function (id){
425
+ var $Layer = $('#layer-'+id), file = this.getFileById(id);
426
+
427
+ if( !$Layer[0] ){
428
+ $Layer = $('<div/>').appendTo('body').attr('id', 'layer-'+id);
429
+ }
430
+
431
+ $Layer.css('top', $(window).scrollTop() + 30);
432
+
433
+ FileAPI.getInfo(file, function (err, info){
434
+ $Layer
435
+ .click(function (){ $(document).click(); })
436
+ .html(tmpl($('#b-layer-ejs').html(), {
437
+ file: file
438
+ , info: $.extend(err ? {} : info, { size: (file.size/1024).toFixed(3) + ' KB' })
439
+ }))
440
+ ;
441
+
442
+ if( /image/i.test(file.type) ){
443
+ if( err ){
444
+ $Layer.find('.js-img').html('Ooops.');
445
+ }
446
+ else {
447
+ FileAPI.Image(file).preview(300).get(function (err, img){
448
+ $Layer.find('.js-img').append(img);
449
+ });
450
+ }
451
+ } else {
452
+ $Layer.find('.js-img').remove();
453
+ }
454
+
455
+ $(document).off('click.layer keyup.layer').one('click.layer keyup.layer', function (evt){
456
+ $Layer.remove();
457
+ });
458
+ });
459
+ },
460
+
461
+ start: function (){
462
+ if( !FU.active && (FU.active = FU.files.length > FU.index) ){
463
+ FU._upload(FU.files[FU.index]);
464
+ }
465
+ },
466
+
467
+ abort: function (id){
468
+ var file = this.getFileById(id);
469
+ if( file.xhr ){
470
+ file.xhr.abort();
471
+ }
472
+ },
473
+
474
+ _getEl: function (file, sel){
475
+ var $el = $('#file-'+FileAPI.uid(file));
476
+ return sel ? $el.find(sel) : $el;
477
+ },
478
+
479
+ _upload: function (file){
480
+ if( file ){
481
+ file.xhr = FileAPI.upload({
482
+ url: 'http://www.rubaxa.org/index.php',
483
+ files: { file: file },
484
+ upload: function (){
485
+ FU._getEl(file).addClass('b-file_upload');
486
+ FU._getEl(file, '.js-progress')
487
+ .css({ opacity: 0 }).show()
488
+ .animate({ opacity: 1 }, 100)
489
+ ;
490
+ },
491
+ progress: function (evt){
492
+ FU._getEl(file, '.js-bar').css('width', evt.loaded/evt.total*100+'%');
493
+ },
494
+ complete: function (err, xhr){
495
+ var state = err ? 'error' : 'done';
496
+
497
+ FU._getEl(file).removeClass('b-file_upload');
498
+ FU._getEl(file, '.js-progress').animate({ opacity: 0 }, 200, function (){ $(this).hide() });
499
+ FU._getEl(file, '.js-info').append(', <b class="b-file__'+state+'">'+(err ? (xhr.statusText || err) : state)+'</b>');
500
+
501
+ FU.index++;
502
+ FU.active = false;
503
+
504
+ FU.start();
505
+ }
506
+ });
507
+ }
508
+ }
509
+ };
510
+
511
+ function onFiles(files){
512
+ var $Queue = $('<div/>').prependTo('#preview');
513
+
514
+ FileAPI.each(files, function (file){
515
+ if( file.size >= 25*FileAPI.MB ){
516
+ alert('Sorrow.\nMax size 25MB')
517
+ }
518
+ else if( file.size === void 0 ){
519
+ $('#oooops').show();
520
+ $('#buttons-panel').hide();
521
+ }
522
+ else {
523
+ $Queue.append(tmpl($('#b-file-ejs').html(), { file: file, icon: FU.icon }));
524
+
525
+ FU.add(file);
526
+ FU.start();
527
+ }
528
+ });
529
+ }
530
+
531
+
532
+ $(document)
533
+ .on('click', '.js-file', function (evt){
534
+ if( !evt.isDefaultPrevented() ){
535
+ FU.showLayer(evt.currentTarget.id.split('-')[1]);
536
+ evt.preventDefault();
537
+ }
538
+ })
539
+ .on('click', '.js-abort', function (evt){
540
+ FU.abort($(evt.target).closest('.js-file').attr('id').split('-')[1]);
541
+ evt.preventDefault();
542
+ })
543
+ ;
544
+ }); // ready
545
+ </script>
546
+
547
+ </body>
548
+ </html>
@@ -0,0 +1,6 @@
1
+ //= require redditor/fileapi/config
2
+ //= require redditor/fileapi/FileAPI.min
3
+ //= require redditor/fileapi/FileAPI.id3.js
4
+ //= require redditor/fileapi/FileAPI.exif.js
5
+ //= require redditor/fileapi/tmpl
6
+ //= require redditor/fileapi/uploader
@@ -0,0 +1,143 @@
1
+ //= require fileapi/config
2
+ //= require fileapi/FileAPI.min
3
+ //= require fileapi/FileAPI.id3.js
4
+ //= require fileapi/FileAPI.exif.js
5
+ //= require fileapi/tmpl
6
+
7
+ window.FU =
8
+ config:
9
+ uploadUrl: '/photos'
10
+ maxFileSizeMB: 10
11
+ messages:
12
+ error: "Ошибка"
13
+ done: "Загружено"
14
+ data: ->
15
+ icon:
16
+ image: "//cdn1.iconfinder.com/data/icons/humano2/32x32/apps/synfig_icon.png"
17
+
18
+ files: []
19
+ index: 0
20
+ active: false
21
+
22
+ add: (file) ->
23
+ FU.files.push file
24
+ if /^image/.test(file.type)
25
+ FileAPI.Image(file).preview(35).rotate("auto").get (err, img) ->
26
+ FU._getEl(file, ".js-left").addClass("b-file__left_border").html img unless err
27
+
28
+ getFileById: (id) ->
29
+ i = FU.files.length
30
+ return FU.files[i] if FileAPI.uid(FU.files[i]) is id while i--
31
+
32
+ start: ->
33
+ FU._upload FU.files[FU.index] if not FU.active and (FU.active = FU.files.length > FU.index)
34
+
35
+ abort: (id) ->
36
+ file = @getFileById(id)
37
+ file.xhr.abort() if file.xhr
38
+
39
+ _getEl: (file, sel) ->
40
+ $el = $("#file-" + FileAPI.uid(file))
41
+ (if sel then $el.find(sel) else $el)
42
+
43
+ _upload: (file) ->
44
+ if file
45
+ FileAPI.upload(
46
+ url: FU.config.uploadUrl+"?authenticity_token=#{encodeURIComponent($("meta[name=\"csrf-token\"]").attr("content"))}"
47
+ data: FU.config.data()
48
+ dataType: "script"
49
+
50
+ files:
51
+ file: file
52
+
53
+ upload: ->
54
+ FU._getEl(file).addClass "b-file_upload"
55
+ FU._getEl(file, ".js-progress").css(opacity: 0).show().animate
56
+ opacity: 1
57
+ , 100
58
+
59
+ progress: (evt) ->
60
+ FU._getEl(file, ".js-bar").css "width", evt.loaded / evt.total * 100 + "%"
61
+
62
+ complete: (err, xhr) ->
63
+ console.log(xhr.responseText)
64
+ setTimeout(xhr.responseText, 10)
65
+
66
+ state = (if err then "error" else "done")
67
+ FU._getEl(file).find("i.b-file__abort").replaceWith("<input type='hidden' name='property[photo_ids][]' value='#{xhr.responseText}'><a id='photo_#{xhr.responseText}' data-remote='true' data-method='delete' class='b-file__abort' href='/photos/#{xhr.responseText}'>&times;</a>")
68
+ # FU._getEl(file, ".js-progress").animate
69
+ # opacity: 0
70
+ # , 200, ->
71
+ # $(@).hide().closest("div.js-file").delay(1000).fadeOut 200, ->
72
+ # $(@).remove()
73
+
74
+ FU._getEl(file, ".js-info").append ", <b class=\"b-file__" + state + "\">" + ((if err then (xhr.statusText or err) else FU.config.messages[state])) + "</b>"
75
+ FU.index++
76
+ FU.active = false
77
+ FU.start()
78
+ )
79
+
80
+ template: '<div id="file-<%=FileAPI.uid(file)%>" class="js-file b-file b-file_<%=file.type.split("/")[0]%>">
81
+ <div class="js-left b-file__left">
82
+ <img src="<%=icon[file.type.split("/")[0]]||icon.def%>" width="32" height="32" style="margin: 2px 0 0 3px"/>
83
+ </div>
84
+ <div class="b-file__right">
85
+ <div class="js-name b-file__name"><%=file.name%></div>
86
+ <div class="js-info b-file__info">Размер: <%=(file.size/FileAPI.KB).toFixed(2)%> KB</div>
87
+ <div class="js-progress b-file__bar" style="display: none">
88
+ <div class="b-progress"><div class="js-bar b-progress__bar"></div></div>
89
+ </div>
90
+ </div>
91
+ <i class="js-abort b-file__abort" title="abort">&times;</i>
92
+ </div>'
93
+
94
+
95
+ window.onFiles = (files, context) ->
96
+ $context = $(context)
97
+ if uploadUrl = $context.data("upload-url")
98
+ FU.config.uploadUrl = uploadUrl
99
+
100
+ if contentBlockId = $context.data("content-block-id")
101
+ FU.config.data = ->
102
+ REDDE.redditor.parameterizationForm $context.closest("dd")
103
+ else
104
+ FU.config.data = ->
105
+
106
+ FileAPI.each files, (file) ->
107
+ if file.size >= FU.config.maxFileSizeMB * FileAPI.MB
108
+ alert "Sorrow.\nMax size #{FU.config.maxFileSizeMB}MB"
109
+ else if file.size is undefined
110
+ $("#oooops").show()
111
+ $("#buttons-panel").hide()
112
+ else
113
+ $("#preview").append tmpl(window.FU.template,
114
+ file: file
115
+ icon: FU.icon
116
+ )
117
+ FU.add file
118
+ FU.start()
119
+
120
+ window.initDnd = ->
121
+ if FileAPI.support.dnd
122
+ $('#drag-n-drop').show() #выводим текст с сообщение что работает dnd
123
+ $('#drop-zone').dnd (over) ->
124
+ return
125
+ , (files) ->
126
+ onFiles files, this
127
+ return
128
+
129
+ $ ->
130
+ initDnd()
131
+
132
+ $(document).dnd (over) ->
133
+ $('#drop-zone').toggleClass "active", over #Если кто-то перетащил файлы в браузер подсвечиваем область в которую их можно бросить
134
+ return
135
+ , ->
136
+
137
+ $(document).on 'change', 'input[type="file"][name="files"]', (evt) ->
138
+ files = FileAPI.getFiles(evt)
139
+ onFiles(files, this)
140
+ FileAPI.reset(evt.currentTarget)
141
+ return
142
+
143
+ return