aerogel-media 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +14 -0
  6. data/Rakefile +1 -0
  7. data/aerogel-media.gemspec +26 -0
  8. data/app/helpers/README.md +7 -0
  9. data/app/helpers/image_tag.rb +26 -0
  10. data/app/routes/README.md +7 -0
  11. data/assets/README.md +1 -0
  12. data/assets/javascripts/aerogel-media.js.coffee +4 -0
  13. data/assets/javascripts/aerogel-media/enable-fancybox.js.coffee +36 -0
  14. data/assets/javascripts/aerogel-media/smart-file-input.js.coffee +132 -0
  15. data/assets/stylesheets/aerogel-media.css.scss +2 -0
  16. data/assets/stylesheets/aerogel-media/smart-file-input.css.scss +12 -0
  17. data/assets/vendor/fancybox2.css.scss +1 -0
  18. data/assets/vendor/fancybox2.js.coffee +1 -0
  19. data/assets/vendor/fancybox2/blank.gif +0 -0
  20. data/assets/vendor/fancybox2/fancybox_loading.gif +0 -0
  21. data/assets/vendor/fancybox2/fancybox_loading@2x.gif +0 -0
  22. data/assets/vendor/fancybox2/fancybox_overlay.png +0 -0
  23. data/assets/vendor/fancybox2/fancybox_sprite.png +0 -0
  24. data/assets/vendor/fancybox2/fancybox_sprite@2x.png +0 -0
  25. data/assets/vendor/fancybox2/helpers/fancybox_buttons.png +0 -0
  26. data/assets/vendor/fancybox2/helpers/jquery.fancybox-buttons.css +97 -0
  27. data/assets/vendor/fancybox2/helpers/jquery.fancybox-buttons.js +122 -0
  28. data/assets/vendor/fancybox2/helpers/jquery.fancybox-media.js +199 -0
  29. data/assets/vendor/fancybox2/helpers/jquery.fancybox-thumbs.css +55 -0
  30. data/assets/vendor/fancybox2/helpers/jquery.fancybox-thumbs.js +162 -0
  31. data/assets/vendor/fancybox2/jquery.fancybox.css +274 -0
  32. data/assets/vendor/fancybox2/jquery.fancybox.js +2020 -0
  33. data/assets/vendor/fancybox2/jquery.fancybox.pack.js +46 -0
  34. data/config/README.md +3 -0
  35. data/config/development/.keep +0 -0
  36. data/config/production/.keep +0 -0
  37. data/db/model/README.md +1 -0
  38. data/db/seed/README.md +1 -0
  39. data/db/seed/development/.keep +0 -0
  40. data/db/seed/production/.keep +0 -0
  41. data/db/seed/seed.template +42 -0
  42. data/lib/aerogel/media.rb +19 -0
  43. data/lib/aerogel/media/core.rb +46 -0
  44. data/lib/aerogel/media/field_types.rb +61 -0
  45. data/lib/aerogel/media/model.rb +60 -0
  46. data/lib/aerogel/media/uploaded_file.rb +15 -0
  47. data/lib/aerogel/media/version.rb +5 -0
  48. data/locales/aerogel-forms.en.yml +8 -0
  49. data/locales/aerogel-forms.ru.yml +8 -0
  50. data/locales/models.en.yml +14 -0
  51. data/locales/models.ru.yml +13 -0
  52. data/public/README.md +1 -0
  53. data/rake/README.md +3 -0
  54. data/views/README.md +1 -0
  55. data/views/form_builder/standard/field_media-file.erb +48 -0
  56. data/views/form_builder/standard/field_media-image.erb +50 -0
  57. metadata +155 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fe40bd030f53130426c4a1fe9dfcf65922bf190b
4
+ data.tar.gz: 74bbe19b21e6499bdada92860a42ff56edb72f1c
5
+ SHA512:
6
+ metadata.gz: b11fb5a178b46a6b4cbe8e1fa0fcbea9a42e548fc412915a48cdc7086f7f8e0a812fbc4da5e4feef3cf14749ba1edd32012af53f0d85c0640861f14e3d953fa9
7
+ data.tar.gz: 8b802f2413779029e8a02e8c2e2c0f4f62e606fd237fc197b43c39e19b57a14b3a127b662de55bf0cbe4ed06984e8da70c5720fdd5522550f7e5d4b0891fe317
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in aerogel-module123.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Alex Kukushkin
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,14 @@
1
+ # Aerogel::Media
2
+
3
+ File attachments for aerogel models.
4
+
5
+ ## Usage
6
+
7
+
8
+ In your application's config.ru:
9
+ ```ruby
10
+ require 'aerogel/core'
11
+ require 'aerogel/media' #
12
+
13
+ run Aerogel::Application.load
14
+ ```
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'aerogel/media/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "aerogel-media"
8
+ spec.version = Aerogel::Media::VERSION
9
+ spec.authors = ["Alex Kukushkin"]
10
+ spec.email = ["alex@kukushk.in"]
11
+ spec.description = %q{File attachments for aerogel models}
12
+ spec.summary = %q{File attachments for aerogel models}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "aerogel-core", "~> 1.4"
22
+ spec.add_dependency "dragonfly"
23
+
24
+ spec.add_development_dependency "bundler", "~> 1.3"
25
+ spec.add_development_dependency "rake"
26
+ end
@@ -0,0 +1,7 @@
1
+ Module helpers go there. Suggested format is:
2
+
3
+ ```ruby
4
+ def my_helper_name1
5
+ ...
6
+ end
7
+ ```
@@ -0,0 +1,26 @@
1
+ # Renders an IMG tag using given Dragonfly job:
2
+ #
3
+ # <%= image_tag @user.avatar.thumb('100x100') %> # => <img src="..." width="..." height="..." .../>
4
+ #
5
+ def image_tag( src, opts = {} )
6
+ if ( src.try(:image?) rescue false )
7
+ tag :img, { src: src.url, width: src.width, height: src.height }.merge(opts)
8
+ else
9
+ h "<not an image!>"
10
+ end
11
+ end
12
+
13
+
14
+ # Renders an IMG for a given +thumb+ enclosed in A.fancybox
15
+ #
16
+ # <%= image_thumb_tag @user.avatar, '100x100' %>
17
+ #
18
+ def image_thumb_tag( src, thumb, opts = {} )
19
+ if ( src.try(:image?) rescue false )
20
+ tag :a, { href: src.url, class: 'fancybox', title: src.description }.merge(opts) do
21
+ image_tag src.thumb(thumb)
22
+ end
23
+ else
24
+ h "<not an image!>"
25
+ end
26
+ end
@@ -0,0 +1,7 @@
1
+ Module routes go there. Suggested format is:
2
+
3
+ ```ruby
4
+ get "/route/to/my/module" do
5
+ ...
6
+ end
7
+ ```
@@ -0,0 +1 @@
1
+ All subfolders of this one will be served by Sprockets pipeline. Exact names, i.e. ```css/``` and ```scripts/```, are irrelevant and serve only for better organization of assets.
@@ -0,0 +1,4 @@
1
+ #= require fancybox2
2
+ #= require_tree ./aerogel-media
3
+
4
+ console?.log "** aerogel-media: initialized"
@@ -0,0 +1,36 @@
1
+ fancybox_options =
2
+ padding: 0
3
+ openSpeed: 100
4
+ closeSpeed: 50
5
+ helpers:
6
+ title:
7
+ type: 'outside'
8
+
9
+
10
+ # Opens fancybox attached to <A HREF=...> tag specified by +el+ element .
11
+ #
12
+ fancybox_open_a_href = (el) ->
13
+ href = $(el).attr 'href'
14
+ title = $(el).attr 'title'
15
+ $.fancybox.open([{ href: href, title: title }], fancybox_options )
16
+ console?.log "** fancybox: called handler on A HREF:#{href}, title:#{title}"
17
+
18
+ # Opens fancybox attached to <IMG SRC=...> tag specified by +el+ element .
19
+ #
20
+ fancybox_open_img_src = (el) ->
21
+ href = $(el).attr 'src'
22
+ title = $(el).attr 'title'
23
+ $.fancybox.open([{ href: href, title: title }], fancybox_options )
24
+ console?.log "** fancybox: called handler on IMG SRC title:#{title}"
25
+
26
+ $ ->
27
+ $("body").on 'click', "A.fancybox", (e) ->
28
+ fancybox_open_a_href this
29
+ e.preventDefault()
30
+ $("body").on 'click', "IMG.fancybox", (e) ->
31
+ fancybox_open_img_src this
32
+ e.preventDefault()
33
+ $("body").on 'mouseenter', "IMG.fancybox", (e) ->
34
+ $(this).css('cursor', 'pointer')
35
+
36
+ console?.log "** fancybox: event handlers installed"
@@ -0,0 +1,132 @@
1
+ # Enables smart-file-input widget on element, specified by +widget+
2
+ #
3
+ # Suggested markup:
4
+ #
5
+ # <div class="smart-file-input">
6
+ #
7
+ # <input type="file" name="..."/>
8
+ # <input class="file-remove-field" type="..." name="..."/>
9
+ #
10
+ # <div class="file-empty">
11
+ # ...no file selected...
12
+ # <button class="btn-file-select">Choose file...</button>
13
+ # </div>
14
+ #
15
+ # <div class="file-exists">
16
+ # <div class="file-old">
17
+ # ...previously uploaded file...
18
+ # </div>
19
+ # <div class="file-new">
20
+ # ...preview or name for selected file...
21
+ # </div>
22
+ # <button class="btn-file-change">Change</button>
23
+ # <button class="btn-file-remove">Remove</button>
24
+ # </div>
25
+ #
26
+ # </div>
27
+ #
28
+ @smart_file_input = (widget) ->
29
+ if widget.hasClass 'smart-file-input-applied'
30
+ console?.log "** smart-file-input: already applied, aborting", widget
31
+ return
32
+ widget.addClass "smart-file-input-applied"
33
+ input_tag = widget.find 'input[type=file]'
34
+ input_remove_tag = widget.find 'input.file-remove-field'
35
+ btn_select = widget.find '.btn-file-select'
36
+ btn_change = widget.find '.btn-file-change'
37
+ btn_remove = widget.find '.btn-file-remove'
38
+ el_file_empty = widget.find '.file-empty'
39
+ el_file_exists = widget.find '.file-exists'
40
+ el_file_exists_old = widget.find '.file-old'
41
+ has_old_file = el_file_exists_old.length > 0
42
+ el_file_exists_new = widget.find '.file-new'
43
+ input_tag.hide()
44
+ el_file_exists_new.hide()
45
+ if has_old_file
46
+ el_file_empty.hide()
47
+ else
48
+ el_file_exists.hide()
49
+ btn_select.on 'click', (e) ->
50
+ e.preventDefault()
51
+ input_tag.trigger 'click'
52
+ btn_change.on 'click', (e) ->
53
+ e.preventDefault()
54
+ input_tag.trigger 'click'
55
+ btn_remove.on 'click', (e) ->
56
+ e.preventDefault()
57
+ on_file_remove()
58
+ input_tag.on 'change', (e) ->
59
+ numFiles = ( if input_tag.get(0).files then input_tag.get(0).files.length else 1 )
60
+ file = input_tag.get(0).files[0] if numFiles > 0
61
+ re = new RegExp '\\\\', 'g'
62
+ label = input_tag.val().replace(re, '/').replace(/.*\//, '')
63
+ console?.log "** smart-file-input: selected #{numFiles}, '#{label}'"
64
+ if numFiles
65
+ # file selected, show new file
66
+ on_file_selected( file, numFiles, label )
67
+ else
68
+ # file selection cancelled, show previous state
69
+ on_file_cancelled()
70
+
71
+ on_file_remove = ->
72
+ el_file_empty.show()
73
+ el_file_exists.hide()
74
+ has_old_file = false
75
+ input_remove_tag.val('1')
76
+ input_tag_reset()
77
+ console?.log "** smart-file-input: remove file, selected or old"
78
+
79
+ on_file_selected = ( file, num, label ) ->
80
+ input_remove_tag.val('') # cancel remove
81
+ el_file_empty.hide()
82
+ el_file_exists_old.hide() # if has_old_file
83
+ el_file_exists_new.find('.file-label').text label
84
+ show_file_preview file, label
85
+ el_file_exists_new.show()
86
+ el_file_exists.show()
87
+
88
+ on_file_cancelled = ->
89
+ if has_old_file
90
+ # file selection cancelled, show old file
91
+ el_file_empty.hide()
92
+ el_file_exists_old.show()
93
+ el_file_exists_new.hide()
94
+ el_file_exists.show()
95
+ else
96
+ # file selection cancelled, no old file
97
+ input_remove_tag.val('1') # re-enable remove
98
+ el_file_empty.show()
99
+ el_file_exists.hide()
100
+
101
+ input_tag_reset = ->
102
+ input_tag.wrap('<form>').parent('form').trigger('reset')
103
+ input_tag.unwrap()
104
+
105
+ show_file_preview = (file, label) ->
106
+ file_ext = file.name.split('.')[-1..][0] if file.name?
107
+ el_file_preview = el_file_exists_new.find '.file-preview'
108
+ if ( el_file_preview.length &&
109
+ file.type? && file.type.match('image.*') &&
110
+ file_ext? && file_ext.match(/^(gif|png|jpe?g)$/i) &&
111
+ FileReader?
112
+ )
113
+ reader = new FileReader()
114
+ reader.onload = (e) ->
115
+ el_file_preview.get(0).src = e.target.result
116
+ reader.readAsDataURL file
117
+ el_file_preview.attr 'title', label
118
+ el_file_preview.show()
119
+ console?.log "** smart-file-input: show file preview"
120
+ else
121
+ el_file_preview.hide()
122
+ console?.log "** smart-file-input: hide file preview"
123
+
124
+ console?.log "** smart-file-input: applied to element"
125
+
126
+
127
+ # Apply on ready
128
+ $ ->
129
+ $(".smart-file-input").each ->
130
+ smart_file_input $(@)
131
+ console?.log "** smart-file-input: loaded"
132
+
@@ -0,0 +1,2 @@
1
+ //= require fancybox2
2
+ //= require_tree ./aerogel-media
@@ -0,0 +1,12 @@
1
+ .smart-file-input {
2
+ .file-empty .btn-file-select,
3
+ .file-exists .btn-file-change,
4
+ .file-exists .btn-file-remove {
5
+ margin-top: 5px;
6
+ }
7
+
8
+ .file-label {
9
+ color: #aaa;
10
+ font-size: 0.9em;
11
+ }
12
+ }
@@ -0,0 +1 @@
1
+ @import "./fancybox2/jquery.fancybox";
@@ -0,0 +1 @@
1
+ #= require fancybox2/jquery.fancybox
@@ -0,0 +1,97 @@
1
+ #fancybox-buttons {
2
+ position: fixed;
3
+ left: 0;
4
+ width: 100%;
5
+ z-index: 8050;
6
+ }
7
+
8
+ #fancybox-buttons.top {
9
+ top: 10px;
10
+ }
11
+
12
+ #fancybox-buttons.bottom {
13
+ bottom: 10px;
14
+ }
15
+
16
+ #fancybox-buttons ul {
17
+ display: block;
18
+ width: 166px;
19
+ height: 30px;
20
+ margin: 0 auto;
21
+ padding: 0;
22
+ list-style: none;
23
+ border: 1px solid #111;
24
+ border-radius: 3px;
25
+ -webkit-box-shadow: inset 0 0 0 1px rgba(255,255,255,.05);
26
+ -moz-box-shadow: inset 0 0 0 1px rgba(255,255,255,.05);
27
+ box-shadow: inset 0 0 0 1px rgba(255,255,255,.05);
28
+ background: rgb(50,50,50);
29
+ background: -moz-linear-gradient(top, rgb(68,68,68) 0%, rgb(52,52,52) 50%, rgb(41,41,41) 50%, rgb(51,51,51) 100%);
30
+ background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,rgb(68,68,68)), color-stop(50%,rgb(52,52,52)), color-stop(50%,rgb(41,41,41)), color-stop(100%,rgb(51,51,51)));
31
+ background: -webkit-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%);
32
+ background: -o-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%);
33
+ background: -ms-linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%);
34
+ background: linear-gradient(top, rgb(68,68,68) 0%,rgb(52,52,52) 50%,rgb(41,41,41) 50%,rgb(51,51,51) 100%);
35
+ filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#444444', endColorstr='#222222',GradientType=0 );
36
+ }
37
+
38
+ #fancybox-buttons ul li {
39
+ float: left;
40
+ margin: 0;
41
+ padding: 0;
42
+ }
43
+
44
+ #fancybox-buttons a {
45
+ display: block;
46
+ width: 30px;
47
+ height: 30px;
48
+ text-indent: -9999px;
49
+ background-color: transparent;
50
+ background-image: url('fancybox_buttons.png');
51
+ background-repeat: no-repeat;
52
+ outline: none;
53
+ opacity: 0.8;
54
+ }
55
+
56
+ #fancybox-buttons a:hover {
57
+ opacity: 1;
58
+ }
59
+
60
+ #fancybox-buttons a.btnPrev {
61
+ background-position: 5px 0;
62
+ }
63
+
64
+ #fancybox-buttons a.btnNext {
65
+ background-position: -33px 0;
66
+ border-right: 1px solid #3e3e3e;
67
+ }
68
+
69
+ #fancybox-buttons a.btnPlay {
70
+ background-position: 0 -30px;
71
+ }
72
+
73
+ #fancybox-buttons a.btnPlayOn {
74
+ background-position: -30px -30px;
75
+ }
76
+
77
+ #fancybox-buttons a.btnToggle {
78
+ background-position: 3px -60px;
79
+ border-left: 1px solid #111;
80
+ border-right: 1px solid #3e3e3e;
81
+ width: 35px
82
+ }
83
+
84
+ #fancybox-buttons a.btnToggleOn {
85
+ background-position: -27px -60px;
86
+ }
87
+
88
+ #fancybox-buttons a.btnClose {
89
+ border-left: 1px solid #111;
90
+ width: 35px;
91
+ background-position: -56px 0px;
92
+ }
93
+
94
+ #fancybox-buttons a.btnDisabled {
95
+ opacity : 0.4;
96
+ cursor: default;
97
+ }