aerogel-media 1.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +14 -0
- data/Rakefile +1 -0
- data/aerogel-media.gemspec +26 -0
- data/app/helpers/README.md +7 -0
- data/app/helpers/image_tag.rb +26 -0
- data/app/routes/README.md +7 -0
- data/assets/README.md +1 -0
- data/assets/javascripts/aerogel-media.js.coffee +4 -0
- data/assets/javascripts/aerogel-media/enable-fancybox.js.coffee +36 -0
- data/assets/javascripts/aerogel-media/smart-file-input.js.coffee +132 -0
- data/assets/stylesheets/aerogel-media.css.scss +2 -0
- data/assets/stylesheets/aerogel-media/smart-file-input.css.scss +12 -0
- data/assets/vendor/fancybox2.css.scss +1 -0
- data/assets/vendor/fancybox2.js.coffee +1 -0
- data/assets/vendor/fancybox2/blank.gif +0 -0
- data/assets/vendor/fancybox2/fancybox_loading.gif +0 -0
- data/assets/vendor/fancybox2/fancybox_loading@2x.gif +0 -0
- data/assets/vendor/fancybox2/fancybox_overlay.png +0 -0
- data/assets/vendor/fancybox2/fancybox_sprite.png +0 -0
- data/assets/vendor/fancybox2/fancybox_sprite@2x.png +0 -0
- data/assets/vendor/fancybox2/helpers/fancybox_buttons.png +0 -0
- data/assets/vendor/fancybox2/helpers/jquery.fancybox-buttons.css +97 -0
- data/assets/vendor/fancybox2/helpers/jquery.fancybox-buttons.js +122 -0
- data/assets/vendor/fancybox2/helpers/jquery.fancybox-media.js +199 -0
- data/assets/vendor/fancybox2/helpers/jquery.fancybox-thumbs.css +55 -0
- data/assets/vendor/fancybox2/helpers/jquery.fancybox-thumbs.js +162 -0
- data/assets/vendor/fancybox2/jquery.fancybox.css +274 -0
- data/assets/vendor/fancybox2/jquery.fancybox.js +2020 -0
- data/assets/vendor/fancybox2/jquery.fancybox.pack.js +46 -0
- data/config/README.md +3 -0
- data/config/development/.keep +0 -0
- data/config/production/.keep +0 -0
- data/db/model/README.md +1 -0
- data/db/seed/README.md +1 -0
- data/db/seed/development/.keep +0 -0
- data/db/seed/production/.keep +0 -0
- data/db/seed/seed.template +42 -0
- data/lib/aerogel/media.rb +19 -0
- data/lib/aerogel/media/core.rb +46 -0
- data/lib/aerogel/media/field_types.rb +61 -0
- data/lib/aerogel/media/model.rb +60 -0
- data/lib/aerogel/media/uploaded_file.rb +15 -0
- data/lib/aerogel/media/version.rb +5 -0
- data/locales/aerogel-forms.en.yml +8 -0
- data/locales/aerogel-forms.ru.yml +8 -0
- data/locales/models.en.yml +14 -0
- data/locales/models.ru.yml +13 -0
- data/public/README.md +1 -0
- data/rake/README.md +3 -0
- data/views/README.md +1 -0
- data/views/form_builder/standard/field_media-file.erb +48 -0
- data/views/form_builder/standard/field_media-image.erb +50 -0
- metadata +155 -0
checksums.yaml
ADDED
@@ -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
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -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.
|
data/README.md
ADDED
data/Rakefile
ADDED
@@ -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,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
|
data/assets/README.md
ADDED
@@ -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,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 @@
|
|
1
|
+
@import "./fancybox2/jquery.fancybox";
|
@@ -0,0 +1 @@
|
|
1
|
+
#= require fancybox2/jquery.fancybox
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
@@ -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
|
+
}
|