radiant-assets-extension 0.0.4 → 0.0.5
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/app/controllers/admin/assets_controller.rb +24 -0
- data/app/helpers/assets_helper.rb +4 -9
- data/app/models/asset.rb +2 -2
- data/app/views/admin/assets/edit.html.erb +2 -3
- data/app/views/admin/assets/index.html.erb +1 -1
- data/app/views/admin/assets/new.html.erb +41 -4
- data/lib/radiant-assets-extension/version.rb +1 -1
- data/lib/tasks/assets_extension_tasks.rake +4 -4
- data/public/jquery.fileupload/.gitignore +1 -0
- data/public/jquery.fileupload/jquery.fileupload-ui.css +74 -0
- data/public/jquery.fileupload/jquery.fileupload-ui.js +308 -0
- data/public/jquery.fileupload/jquery.fileupload.js +629 -0
- data/public/jquery.fileupload/pbar-ani.gif +0 -0
- data/public/stylesheets/admin/extensions/assets/assets.css +2 -1
- metadata +9 -4
@@ -1,4 +1,28 @@
|
|
1
1
|
class Admin::AssetsController < Admin::ResourceController
|
2
2
|
paginate_models
|
3
3
|
helper :assets
|
4
|
+
|
5
|
+
def create
|
6
|
+
# HACK: depends on javascript being present and packaging each file
|
7
|
+
# in its own request
|
8
|
+
# TODO: handle non-js situations with several files in one request
|
9
|
+
@asset = Asset.create! :upload => Array(params[:asset][:upload]).first
|
10
|
+
@asset.save!
|
11
|
+
render_hacky_json(:markup => @template.asset_listing(@asset))
|
12
|
+
rescue => e
|
13
|
+
logger.warn(e.to_s)
|
14
|
+
render_hacky_json(:markup => "Error: #{e.to_s}")
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
# HACK: sending JSON as text/html
|
19
|
+
# (https://github.com/blueimp/jQuery-File-Upload/wiki/Setup)
|
20
|
+
# jquery.fileupload makes use of iframes for browsers like Microsoft
|
21
|
+
# Internet Explorer and Opera, which do not yet support XMLHTTPRequest
|
22
|
+
# uploads. They will only register a load event if the Content-type of the
|
23
|
+
# response is set to text/plain or text/html, not if it is set to
|
24
|
+
# application/json.
|
25
|
+
def render_hacky_json(data)
|
26
|
+
render :json => data, :content_type => 'text/html'
|
27
|
+
end
|
4
28
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module AssetsHelper
|
1
|
+
module AssetsHelper
|
2
2
|
def asset_listing(asset)
|
3
3
|
icon(asset) +
|
4
4
|
content_tag(:span, asset.to_s, :class=>'title')
|
@@ -40,9 +40,7 @@ module AssetsHelper
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def video_player(asset)
|
43
|
-
|
44
|
-
content_tag :source, '', :src => @asset.upload.url, :type => @asset.upload.mime_type
|
45
|
-
end
|
43
|
+
%Q{<video src="#{asset.upload.url}" type="#{asset.upload.mime_type}" controls="controls">}
|
46
44
|
end
|
47
45
|
|
48
46
|
def audio_player(asset)
|
@@ -58,10 +56,7 @@ module AssetsHelper
|
|
58
56
|
end
|
59
57
|
|
60
58
|
def view_toggle
|
61
|
-
|
62
|
-
|
63
|
-
else
|
64
|
-
link_to 'List view', admin_assets_path(:view => 'list')
|
65
|
-
end
|
59
|
+
other = list_view? ? 'grid' : 'list'
|
60
|
+
link_to "Switch to #{other} view", admin_assets_path(:view => other)
|
66
61
|
end
|
67
62
|
end
|
data/app/models/asset.rb
CHANGED
@@ -10,8 +10,8 @@ class Asset < ActiveRecord::Base
|
|
10
10
|
# HACK: relying on extension instead of using analyser and upload.format
|
11
11
|
# analyser can throw us into very long loop when trying to identify
|
12
12
|
# non-image files like word docs
|
13
|
-
upload.ext.to_sym
|
14
|
-
rescue UnableToHandle
|
13
|
+
upload.ext && upload.ext.to_sym
|
14
|
+
rescue Dragonfly::FunctionManager::UnableToHandle
|
15
15
|
:generic
|
16
16
|
end
|
17
17
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
<h1>Edit Asset</h1>
|
4
4
|
|
5
|
-
<% form_for [:admin, @asset], :html => {'data-onsubmit_status' => onsubmit_status(@asset)} do |f| %>
|
5
|
+
<% form_for [:admin, @asset], :html => {:multipart => true, 'data-onsubmit_status' => onsubmit_status(@asset)} do |f| %>
|
6
6
|
<div class="form_area">
|
7
7
|
<p class="title">
|
8
8
|
Caption: <%= f.text_field :caption %>
|
@@ -16,8 +16,7 @@
|
|
16
16
|
<% end %>
|
17
17
|
</tbody>
|
18
18
|
</table>
|
19
|
-
|
20
|
-
<!-- <%= f.file_field :upload %> -->
|
19
|
+
<%= f.file_field :upload %>
|
21
20
|
<%= display(@asset) %>
|
22
21
|
</div>
|
23
22
|
<p class="buttons">
|
@@ -7,7 +7,7 @@
|
|
7
7
|
<div id="actions">
|
8
8
|
<%= pagination_for(@assets) %>
|
9
9
|
<ul>
|
10
|
-
<li class="new"><%= link_to 'Upload New
|
10
|
+
<li class="new"><%= link_to 'Upload New Assets', new_admin_asset_path %></li>
|
11
11
|
<li><%= view_toggle %></li>
|
12
12
|
</ul>
|
13
13
|
</div>
|
@@ -1,8 +1,45 @@
|
|
1
|
-
|
1
|
+
<% include_stylesheet 'admin/extensions/assets/assets' %>
|
2
|
+
|
3
|
+
<h1>Upload New Assets</h1>
|
4
|
+
<table id="files">
|
5
|
+
<tbody></tbody>
|
6
|
+
</table>
|
7
|
+
|
8
|
+
<p>You can select multiple files</p>
|
2
9
|
<% form_for [:admin, @asset], :html => {:multipart => true, 'data-onsubmit_status'=>'Uploading Asset…'} do |f| %>
|
3
|
-
<%= f.file_field :upload %>
|
4
|
-
|
10
|
+
<%= f.file_field :upload, :multiple => true %>
|
11
|
+
|
12
|
+
<!-- <p class="buttons">
|
5
13
|
<%= f.submit 'Upload Asset', :class=>'button' %>
|
6
14
|
or <%= link_to 'Cancel', admin_assets_path %>
|
7
|
-
</p>
|
15
|
+
</p> -->
|
8
16
|
<% end %>
|
17
|
+
|
18
|
+
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js"></script>
|
19
|
+
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js"></script>
|
20
|
+
<% include_stylesheet 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/themes/base/jquery-ui.css' %>
|
21
|
+
<script type="text/javascript">jQuery.noConflict();</script>
|
22
|
+
<script src="/jquery.fileupload/jquery.fileupload.js" type="text/javascript"></script>
|
23
|
+
<script src="/jquery.fileupload/jquery.fileupload-ui.js" type="text/javascript"></script>
|
24
|
+
<% include_stylesheet '/jquery.fileupload/jquery.fileupload-ui.css' %>
|
25
|
+
<script type="text/javascript">
|
26
|
+
(function($) {
|
27
|
+
$(function () {
|
28
|
+
$('form.new_asset').fileUploadUI({
|
29
|
+
uploadTable: $('#files'),
|
30
|
+
downloadTable: $('#files'),
|
31
|
+
buildUploadRow: function (files, index) {
|
32
|
+
return $('<tr><td>' + files[index].name + '<\/td>' +
|
33
|
+
'<td class="file_upload_progress"><div><\/div><\/td>' +
|
34
|
+
'<td class="file_upload_cancel">' +
|
35
|
+
'<button class="ui-state-default ui-corner-all" title="Cancel">' +
|
36
|
+
'<span class="ui-icon ui-icon-cancel">Cancel<\/span>' +
|
37
|
+
'<\/button><\/td><\/tr>');
|
38
|
+
},
|
39
|
+
buildDownloadRow: function (file) {
|
40
|
+
return $('<tr><td>' + file.markup + '<\/td><\/tr>');
|
41
|
+
}
|
42
|
+
});
|
43
|
+
});
|
44
|
+
}(jQuery));
|
45
|
+
</script>
|
@@ -2,7 +2,7 @@ namespace :radiant do
|
|
2
2
|
namespace :extensions do
|
3
3
|
namespace :assets do
|
4
4
|
|
5
|
-
desc "Runs the migration of the
|
5
|
+
desc "Runs the migration of the Assets extension"
|
6
6
|
task :migrate => :environment do
|
7
7
|
require 'radiant/extension_migrator'
|
8
8
|
if ENV["VERSION"]
|
@@ -14,10 +14,10 @@ namespace :radiant do
|
|
14
14
|
end
|
15
15
|
end
|
16
16
|
|
17
|
-
desc "Copies public assets of the
|
17
|
+
desc "Copies public assets of the Assets extension to the instance public/ directory."
|
18
18
|
task :update => :environment do
|
19
19
|
is_svn_or_dir = proc {|path| path =~ /\.svn/ || File.directory?(path) }
|
20
|
-
puts "Copying assets from
|
20
|
+
puts "Copying assets from AssetsExtension"
|
21
21
|
Dir[AssetsExtension.root + "/public/**/*"].reject(&is_svn_or_dir).each do |file|
|
22
22
|
path = file.sub(AssetsExtension.root, '')
|
23
23
|
directory = File.dirname(path)
|
@@ -25,7 +25,7 @@ namespace :radiant do
|
|
25
25
|
cp file, RAILS_ROOT + path, :verbose => false
|
26
26
|
end
|
27
27
|
unless AssetsExtension.root.starts_with? RAILS_ROOT # don't need to copy vendored tasks
|
28
|
-
puts "Copying rake tasks from
|
28
|
+
puts "Copying rake tasks from AssetsExtension"
|
29
29
|
local_tasks_path = File.join(RAILS_ROOT, %w(lib tasks))
|
30
30
|
mkdir_p local_tasks_path, :verbose => false
|
31
31
|
Dir[File.join AssetsExtension.root, %w(lib tasks *.rake)].each do |file|
|
@@ -0,0 +1 @@
|
|
1
|
+
.DS_Store
|
@@ -0,0 +1,74 @@
|
|
1
|
+
.file_upload {
|
2
|
+
position: relative;
|
3
|
+
overflow: hidden;
|
4
|
+
direction: ltr;
|
5
|
+
cursor: pointer;
|
6
|
+
text-align: center;
|
7
|
+
color: #333;
|
8
|
+
font-weight: bold;
|
9
|
+
-moz-border-radius: 10px;
|
10
|
+
-webkit-border-radius: 10px;
|
11
|
+
border-radius: 10px;
|
12
|
+
width: 200px;
|
13
|
+
height: 30px;
|
14
|
+
line-height: 30px;
|
15
|
+
background: palegreen;
|
16
|
+
border: 1px solid limegreen;
|
17
|
+
}
|
18
|
+
|
19
|
+
.file_upload_small {
|
20
|
+
width: 200px;
|
21
|
+
height: 30px;
|
22
|
+
line-height: 30px;
|
23
|
+
font-size: auto;
|
24
|
+
background: palegreen;
|
25
|
+
border: 1px solid limegreen;
|
26
|
+
}
|
27
|
+
|
28
|
+
.file_upload_large {
|
29
|
+
width: 100%;
|
30
|
+
height: 150px;
|
31
|
+
line-height: 150px;
|
32
|
+
font-size: 20px;
|
33
|
+
background: palegreen;
|
34
|
+
border: 1px solid limegreen;
|
35
|
+
}
|
36
|
+
|
37
|
+
.file_upload_highlight {
|
38
|
+
background: lawngreen;
|
39
|
+
}
|
40
|
+
|
41
|
+
.file_upload input {
|
42
|
+
position: absolute;
|
43
|
+
top: 0;
|
44
|
+
right: 0;
|
45
|
+
margin: 0;
|
46
|
+
border: 300px solid transparent;
|
47
|
+
opacity: 0;
|
48
|
+
-ms-filter: 'alpha(opacity=0)';
|
49
|
+
filter: alpha(opacity=0);
|
50
|
+
-o-transform: translate(-300px, -300px) scale(10);
|
51
|
+
-moz-transform: translate(-800px, 0) scale(10);
|
52
|
+
cursor: pointer;
|
53
|
+
}
|
54
|
+
|
55
|
+
.file_upload iframe, .file_upload button {
|
56
|
+
display: none;
|
57
|
+
}
|
58
|
+
|
59
|
+
.file_upload_preview img {
|
60
|
+
width: 80px;
|
61
|
+
}
|
62
|
+
|
63
|
+
.file_upload_progress .ui-progressbar-value {
|
64
|
+
background: url(pbar-ani.gif);
|
65
|
+
}
|
66
|
+
|
67
|
+
.file_upload_progress div {
|
68
|
+
width: 150px;
|
69
|
+
height: 15px;
|
70
|
+
}
|
71
|
+
|
72
|
+
.file_upload_cancel button {
|
73
|
+
cursor: pointer;
|
74
|
+
}
|
@@ -0,0 +1,308 @@
|
|
1
|
+
/*
|
2
|
+
* jQuery File Upload User Interface Plugin 3.6
|
3
|
+
*
|
4
|
+
* Copyright 2010, Sebastian Tschan, AQUANTUM
|
5
|
+
* Licensed under the MIT license:
|
6
|
+
* http://creativecommons.org/licenses/MIT/
|
7
|
+
*
|
8
|
+
* https://blueimp.net
|
9
|
+
* http://www.aquantum.de
|
10
|
+
*/
|
11
|
+
|
12
|
+
/*jslint browser: true */
|
13
|
+
/*global jQuery, FileReader, URL */
|
14
|
+
|
15
|
+
(function ($) {
|
16
|
+
|
17
|
+
var undef = 'undefined',
|
18
|
+
func = 'function',
|
19
|
+
UploadHandler,
|
20
|
+
methods,
|
21
|
+
|
22
|
+
LocalImage = function (file, imageTypes) {
|
23
|
+
var img,
|
24
|
+
fileReader;
|
25
|
+
if (!imageTypes.test(file.type)) {
|
26
|
+
return null;
|
27
|
+
}
|
28
|
+
img = document.createElement('img');
|
29
|
+
if (typeof URL !== undef && typeof URL.createObjectURL === func) {
|
30
|
+
img.src = URL.createObjectURL(file);
|
31
|
+
img.onload = function () {
|
32
|
+
URL.revokeObjectURL(this.src);
|
33
|
+
};
|
34
|
+
return img;
|
35
|
+
}
|
36
|
+
if (typeof FileReader !== undef) {
|
37
|
+
fileReader = new FileReader();
|
38
|
+
if (typeof fileReader.readAsDataURL === func) {
|
39
|
+
fileReader.onload = function (e) {
|
40
|
+
img.src = e.target.result;
|
41
|
+
};
|
42
|
+
fileReader.readAsDataURL(file);
|
43
|
+
return img;
|
44
|
+
}
|
45
|
+
}
|
46
|
+
return null;
|
47
|
+
};
|
48
|
+
|
49
|
+
UploadHandler = function (container, options) {
|
50
|
+
var uploadHandler = this,
|
51
|
+
dragOverTimeout,
|
52
|
+
isDropZoneEnlarged;
|
53
|
+
|
54
|
+
this.dropZone = container;
|
55
|
+
this.imageTypes = /^image\/(gif|jpeg|png)$/;
|
56
|
+
this.previewSelector = '.file_upload_preview';
|
57
|
+
this.progressSelector = '.file_upload_progress div';
|
58
|
+
this.cancelSelector = '.file_upload_cancel button';
|
59
|
+
this.cssClassSmall = 'file_upload_small';
|
60
|
+
this.cssClassLarge = 'file_upload_large';
|
61
|
+
this.cssClassHighlight = 'file_upload_highlight';
|
62
|
+
this.dropEffect = 'highlight';
|
63
|
+
this.uploadTable = this.downloadTable = null;
|
64
|
+
|
65
|
+
this.buildUploadRow = this.buildDownloadRow = function () {
|
66
|
+
return null;
|
67
|
+
};
|
68
|
+
|
69
|
+
this.addNode = function (parentNode, node, callBack) {
|
70
|
+
if (node) {
|
71
|
+
node.css('display', 'none').appendTo(parentNode).fadeIn(function () {
|
72
|
+
if (typeof callBack === func) {
|
73
|
+
try {
|
74
|
+
callBack();
|
75
|
+
} catch (e) {
|
76
|
+
// Fix endless exception loop:
|
77
|
+
$(this).stop();
|
78
|
+
throw e;
|
79
|
+
}
|
80
|
+
}
|
81
|
+
});
|
82
|
+
} else if (typeof callBack === func) {
|
83
|
+
callBack();
|
84
|
+
}
|
85
|
+
};
|
86
|
+
|
87
|
+
this.removeNode = function (node, callBack) {
|
88
|
+
if (node) {
|
89
|
+
node.fadeOut(function () {
|
90
|
+
$(this).remove();
|
91
|
+
if (typeof callBack === func) {
|
92
|
+
try {
|
93
|
+
callBack();
|
94
|
+
} catch (e) {
|
95
|
+
// Fix endless exception loop:
|
96
|
+
$(this).stop();
|
97
|
+
throw e;
|
98
|
+
}
|
99
|
+
}
|
100
|
+
});
|
101
|
+
} else if (typeof callBack === func) {
|
102
|
+
callBack();
|
103
|
+
}
|
104
|
+
};
|
105
|
+
|
106
|
+
this.onAbort = function (event, files, index, xhr, handler) {
|
107
|
+
handler.removeNode(handler.uploadRow);
|
108
|
+
};
|
109
|
+
|
110
|
+
this.cancelUpload = function (event, files, index, xhr, handler) {
|
111
|
+
var readyState = xhr.readyState;
|
112
|
+
xhr.abort();
|
113
|
+
// If readyState is below 2, abort() has no effect:
|
114
|
+
if (isNaN(readyState) || readyState < 2) {
|
115
|
+
handler.onAbort(event, files, index, xhr, handler);
|
116
|
+
}
|
117
|
+
};
|
118
|
+
|
119
|
+
this.initProgressBar = function (node, value) {
|
120
|
+
if (typeof node.progressbar === func) {
|
121
|
+
return node.progressbar({
|
122
|
+
value: value
|
123
|
+
});
|
124
|
+
} else {
|
125
|
+
var progressbar = $('<progress value="' + value + '" max="100"/>').appendTo(node);
|
126
|
+
progressbar.progressbar = function (key, value) {
|
127
|
+
progressbar.attr('value', value);
|
128
|
+
};
|
129
|
+
return progressbar;
|
130
|
+
}
|
131
|
+
};
|
132
|
+
|
133
|
+
this.initUploadRow = function (event, files, index, xhr, handler, callBack) {
|
134
|
+
var uploadRow = handler.uploadRow = handler.buildUploadRow(files, index, handler);
|
135
|
+
if (uploadRow) {
|
136
|
+
handler.progressbar = handler.initProgressBar(
|
137
|
+
uploadRow.find(handler.progressSelector),
|
138
|
+
(xhr.upload ? 0 : 100)
|
139
|
+
);
|
140
|
+
uploadRow.find(handler.cancelSelector).click(function (e) {
|
141
|
+
handler.cancelUpload(e, files, index, xhr, handler);
|
142
|
+
});
|
143
|
+
uploadRow.find(handler.previewSelector).each(function () {
|
144
|
+
$(this).append(new LocalImage(files[index], handler.imageTypes));
|
145
|
+
});
|
146
|
+
}
|
147
|
+
handler.addNode(
|
148
|
+
(typeof handler.uploadTable === func ? handler.uploadTable(handler) : handler.uploadTable),
|
149
|
+
uploadRow,
|
150
|
+
callBack
|
151
|
+
);
|
152
|
+
};
|
153
|
+
|
154
|
+
this.initUpload = function (event, files, index, xhr, handler, callBack) {
|
155
|
+
handler.initUploadRow(event, files, index, xhr, handler, function () {
|
156
|
+
if (typeof handler.beforeSend === func) {
|
157
|
+
handler.beforeSend(event, files, index, xhr, handler, callBack);
|
158
|
+
} else {
|
159
|
+
callBack();
|
160
|
+
}
|
161
|
+
});
|
162
|
+
};
|
163
|
+
|
164
|
+
this.onProgress = function (event, files, index, xhr, handler) {
|
165
|
+
if (handler.progressbar) {
|
166
|
+
handler.progressbar.progressbar(
|
167
|
+
'value',
|
168
|
+
parseInt(event.loaded / event.total * 100, 10)
|
169
|
+
);
|
170
|
+
}
|
171
|
+
};
|
172
|
+
|
173
|
+
this.parseResponse = function (xhr) {
|
174
|
+
if (typeof xhr.responseText !== undef) {
|
175
|
+
return $.parseJSON(xhr.responseText);
|
176
|
+
} else {
|
177
|
+
// Instead of an XHR object, an iframe is used for legacy browsers:
|
178
|
+
return $.parseJSON(xhr.contents().text());
|
179
|
+
}
|
180
|
+
};
|
181
|
+
|
182
|
+
this.initDownloadRow = function (event, files, index, xhr, handler, callBack) {
|
183
|
+
var json, downloadRow;
|
184
|
+
try {
|
185
|
+
json = handler.response = handler.parseResponse(xhr);
|
186
|
+
downloadRow = handler.downloadRow = handler.buildDownloadRow(json, handler);
|
187
|
+
handler.addNode(
|
188
|
+
(typeof handler.downloadTable === func ? handler.downloadTable(handler) : handler.downloadTable),
|
189
|
+
downloadRow,
|
190
|
+
callBack
|
191
|
+
);
|
192
|
+
} catch (e) {
|
193
|
+
if (typeof handler.onError === func) {
|
194
|
+
handler.originalEvent = event;
|
195
|
+
handler.onError(e, files, index, xhr, handler);
|
196
|
+
} else {
|
197
|
+
throw e;
|
198
|
+
}
|
199
|
+
}
|
200
|
+
};
|
201
|
+
|
202
|
+
this.onLoad = function (event, files, index, xhr, handler) {
|
203
|
+
handler.removeNode(handler.uploadRow, function () {
|
204
|
+
handler.initDownloadRow(event, files, index, xhr, handler, function () {
|
205
|
+
if (typeof handler.onComplete === func) {
|
206
|
+
handler.onComplete(event, files, index, xhr, handler);
|
207
|
+
}
|
208
|
+
});
|
209
|
+
});
|
210
|
+
};
|
211
|
+
|
212
|
+
this.dropZoneEnlarge = function () {
|
213
|
+
if (!isDropZoneEnlarged) {
|
214
|
+
if (typeof uploadHandler.dropZone.switchClass === func) {
|
215
|
+
uploadHandler.dropZone.switchClass(
|
216
|
+
uploadHandler.cssClassSmall,
|
217
|
+
uploadHandler.cssClassLarge
|
218
|
+
);
|
219
|
+
} else {
|
220
|
+
uploadHandler.dropZone.addClass(uploadHandler.cssClassLarge);
|
221
|
+
uploadHandler.dropZone.removeClass(uploadHandler.cssClassSmall);
|
222
|
+
}
|
223
|
+
isDropZoneEnlarged = true;
|
224
|
+
}
|
225
|
+
};
|
226
|
+
|
227
|
+
this.dropZoneReduce = function () {
|
228
|
+
if (typeof uploadHandler.dropZone.switchClass === func) {
|
229
|
+
uploadHandler.dropZone.switchClass(
|
230
|
+
uploadHandler.cssClassLarge,
|
231
|
+
uploadHandler.cssClassSmall
|
232
|
+
);
|
233
|
+
} else {
|
234
|
+
uploadHandler.dropZone.addClass(uploadHandler.cssClassSmall);
|
235
|
+
uploadHandler.dropZone.removeClass(uploadHandler.cssClassLarge);
|
236
|
+
}
|
237
|
+
isDropZoneEnlarged = false;
|
238
|
+
};
|
239
|
+
|
240
|
+
this.onDocumentDragEnter = function (event) {
|
241
|
+
uploadHandler.dropZoneEnlarge();
|
242
|
+
};
|
243
|
+
|
244
|
+
this.onDocumentDragOver = function (event) {
|
245
|
+
if (dragOverTimeout) {
|
246
|
+
clearTimeout(dragOverTimeout);
|
247
|
+
}
|
248
|
+
dragOverTimeout = setTimeout(function () {
|
249
|
+
uploadHandler.dropZoneReduce();
|
250
|
+
}, 200);
|
251
|
+
};
|
252
|
+
|
253
|
+
this.onDragEnter = this.onDragLeave = function (event) {
|
254
|
+
uploadHandler.dropZone.toggleClass(uploadHandler.cssClassHighlight);
|
255
|
+
};
|
256
|
+
|
257
|
+
this.onDrop = function (event) {
|
258
|
+
if (dragOverTimeout) {
|
259
|
+
clearTimeout(dragOverTimeout);
|
260
|
+
}
|
261
|
+
if (uploadHandler.dropEffect && typeof uploadHandler.dropZone.effect === func) {
|
262
|
+
uploadHandler.dropZone.effect(uploadHandler.dropEffect, function () {
|
263
|
+
uploadHandler.dropZone.removeClass(uploadHandler.cssClassHighlight);
|
264
|
+
uploadHandler.dropZoneReduce();
|
265
|
+
});
|
266
|
+
} else {
|
267
|
+
uploadHandler.dropZone.removeClass(uploadHandler.cssClassHighlight);
|
268
|
+
uploadHandler.dropZoneReduce();
|
269
|
+
}
|
270
|
+
};
|
271
|
+
|
272
|
+
$.extend(this, options);
|
273
|
+
};
|
274
|
+
|
275
|
+
methods = {
|
276
|
+
init : function (options) {
|
277
|
+
return this.each(function () {
|
278
|
+
$(this).fileUpload(new UploadHandler($(this), options));
|
279
|
+
});
|
280
|
+
},
|
281
|
+
|
282
|
+
option: function (option, value, namespace) {
|
283
|
+
if (typeof option === undef || (typeof option === 'string' && typeof value === undef)) {
|
284
|
+
return $(this).fileUpload('option', option, value, namespace);
|
285
|
+
}
|
286
|
+
return this.each(function () {
|
287
|
+
$(this).fileUpload('option', option, value, namespace);
|
288
|
+
});
|
289
|
+
},
|
290
|
+
|
291
|
+
destroy : function (namespace) {
|
292
|
+
return this.each(function () {
|
293
|
+
$(this).fileUpload('destroy', namespace);
|
294
|
+
});
|
295
|
+
}
|
296
|
+
};
|
297
|
+
|
298
|
+
$.fn.fileUploadUI = function (method) {
|
299
|
+
if (methods[method]) {
|
300
|
+
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
301
|
+
} else if (typeof method === 'object' || !method) {
|
302
|
+
return methods.init.apply(this, arguments);
|
303
|
+
} else {
|
304
|
+
$.error('Method ' + method + ' does not exist on jQuery.fileUploadUI');
|
305
|
+
}
|
306
|
+
};
|
307
|
+
|
308
|
+
}(jQuery));
|
@@ -0,0 +1,629 @@
|
|
1
|
+
/*
|
2
|
+
* jQuery File Upload Plugin 3.7.1
|
3
|
+
*
|
4
|
+
* Copyright 2010, Sebastian Tschan, AQUANTUM
|
5
|
+
* Licensed under the MIT license:
|
6
|
+
* http://creativecommons.org/licenses/MIT/
|
7
|
+
*
|
8
|
+
* https://blueimp.net
|
9
|
+
* http://www.aquantum.de
|
10
|
+
*/
|
11
|
+
|
12
|
+
/*jslint browser: true */
|
13
|
+
/*global File, FileReader, FormData, unescape, jQuery */
|
14
|
+
|
15
|
+
(function ($) {
|
16
|
+
|
17
|
+
var defaultNamespace = 'file_upload',
|
18
|
+
undef = 'undefined',
|
19
|
+
func = 'function',
|
20
|
+
num = 'number',
|
21
|
+
FileUpload,
|
22
|
+
methods,
|
23
|
+
|
24
|
+
MultiLoader = function (callBack, numberComplete) {
|
25
|
+
var loaded = 0;
|
26
|
+
this.complete = function () {
|
27
|
+
loaded += 1;
|
28
|
+
if (loaded === numberComplete) {
|
29
|
+
callBack();
|
30
|
+
}
|
31
|
+
};
|
32
|
+
};
|
33
|
+
|
34
|
+
FileUpload = function (container) {
|
35
|
+
var fileUpload = this,
|
36
|
+
uploadForm,
|
37
|
+
fileInput,
|
38
|
+
settings = {
|
39
|
+
namespace: defaultNamespace,
|
40
|
+
uploadFormFilter: function (index) {
|
41
|
+
return true;
|
42
|
+
},
|
43
|
+
fileInputFilter: function (index) {
|
44
|
+
return true;
|
45
|
+
},
|
46
|
+
cssClass: defaultNamespace,
|
47
|
+
dragDropSupport: true,
|
48
|
+
dropZone: container,
|
49
|
+
url: function (form) {
|
50
|
+
return form.attr('action');
|
51
|
+
},
|
52
|
+
method: function (form) {
|
53
|
+
return form.attr('method');
|
54
|
+
},
|
55
|
+
fieldName: function (input) {
|
56
|
+
return input.attr('name');
|
57
|
+
},
|
58
|
+
formData: function (form) {
|
59
|
+
return form.serializeArray();
|
60
|
+
},
|
61
|
+
multipart: true,
|
62
|
+
multiFileRequest: false,
|
63
|
+
withCredentials: false,
|
64
|
+
forceIframeUpload: false
|
65
|
+
},
|
66
|
+
documentListeners = {},
|
67
|
+
dropZoneListeners = {},
|
68
|
+
protocolRegExp = /^http(s)?:\/\//,
|
69
|
+
optionsReference,
|
70
|
+
|
71
|
+
isXHRUploadCapable = function () {
|
72
|
+
return typeof XMLHttpRequest !== undef && typeof File !== undef && (
|
73
|
+
!settings.multipart || typeof FormData !== undef || typeof FileReader !== undef
|
74
|
+
);
|
75
|
+
},
|
76
|
+
|
77
|
+
initEventHandlers = function () {
|
78
|
+
if (settings.dragDropSupport) {
|
79
|
+
if (typeof settings.onDocumentDragEnter === func) {
|
80
|
+
documentListeners['dragenter.' + settings.namespace] = function (e) {
|
81
|
+
settings.onDocumentDragEnter(e);
|
82
|
+
};
|
83
|
+
}
|
84
|
+
if (typeof settings.onDocumentDragLeave === func) {
|
85
|
+
documentListeners['dragleave.' + settings.namespace] = function (e) {
|
86
|
+
settings.onDocumentDragLeave(e);
|
87
|
+
};
|
88
|
+
}
|
89
|
+
documentListeners['dragover.' + settings.namespace] = fileUpload.onDocumentDragOver;
|
90
|
+
documentListeners['drop.' + settings.namespace] = fileUpload.onDocumentDrop;
|
91
|
+
$(document).bind(documentListeners);
|
92
|
+
if (typeof settings.onDragEnter === func) {
|
93
|
+
dropZoneListeners['dragenter.' + settings.namespace] = function (e) {
|
94
|
+
settings.onDragEnter(e);
|
95
|
+
};
|
96
|
+
}
|
97
|
+
if (typeof settings.onDragLeave === func) {
|
98
|
+
dropZoneListeners['dragleave.' + settings.namespace] = function (e) {
|
99
|
+
settings.onDragLeave(e);
|
100
|
+
};
|
101
|
+
}
|
102
|
+
dropZoneListeners['dragover.' + settings.namespace] = fileUpload.onDragOver;
|
103
|
+
dropZoneListeners['drop.' + settings.namespace] = fileUpload.onDrop;
|
104
|
+
settings.dropZone.bind(dropZoneListeners);
|
105
|
+
}
|
106
|
+
fileInput.bind('change.' + settings.namespace, fileUpload.onChange);
|
107
|
+
},
|
108
|
+
|
109
|
+
removeEventHandlers = function () {
|
110
|
+
$.each(documentListeners, function (key, value) {
|
111
|
+
$(document).unbind(key, value);
|
112
|
+
});
|
113
|
+
$.each(dropZoneListeners, function (key, value) {
|
114
|
+
settings.dropZone.unbind(key, value);
|
115
|
+
});
|
116
|
+
fileInput.unbind('change.' + settings.namespace);
|
117
|
+
},
|
118
|
+
|
119
|
+
initUploadEventHandlers = function (files, index, xhr, settings) {
|
120
|
+
if (typeof settings.onProgress === func) {
|
121
|
+
xhr.upload.onprogress = function (e) {
|
122
|
+
settings.onProgress(e, files, index, xhr, settings);
|
123
|
+
};
|
124
|
+
}
|
125
|
+
if (typeof settings.onLoad === func) {
|
126
|
+
xhr.onload = function (e) {
|
127
|
+
settings.onLoad(e, files, index, xhr, settings);
|
128
|
+
};
|
129
|
+
}
|
130
|
+
if (typeof settings.onAbort === func) {
|
131
|
+
xhr.onabort = function (e) {
|
132
|
+
settings.onAbort(e, files, index, xhr, settings);
|
133
|
+
};
|
134
|
+
}
|
135
|
+
if (typeof settings.onError === func) {
|
136
|
+
xhr.onerror = function (e) {
|
137
|
+
settings.onError(e, files, index, xhr, settings);
|
138
|
+
};
|
139
|
+
}
|
140
|
+
},
|
141
|
+
|
142
|
+
getUrl = function (settings) {
|
143
|
+
if (typeof settings.url === func) {
|
144
|
+
return settings.url(settings.uploadForm || uploadForm);
|
145
|
+
}
|
146
|
+
return settings.url;
|
147
|
+
},
|
148
|
+
|
149
|
+
getMethod = function (settings) {
|
150
|
+
if (typeof settings.method === func) {
|
151
|
+
return settings.method(settings.uploadForm || uploadForm);
|
152
|
+
}
|
153
|
+
return settings.method;
|
154
|
+
},
|
155
|
+
|
156
|
+
getFieldName = function (settings) {
|
157
|
+
if (typeof settings.fieldName === func) {
|
158
|
+
return settings.fieldName(settings.fileInput || fileInput);
|
159
|
+
}
|
160
|
+
return settings.fieldName;
|
161
|
+
},
|
162
|
+
|
163
|
+
getFormData = function (settings) {
|
164
|
+
var formData;
|
165
|
+
if (typeof settings.formData === func) {
|
166
|
+
return settings.formData(settings.uploadForm || uploadForm);
|
167
|
+
} else if ($.isArray(settings.formData)) {
|
168
|
+
return settings.formData;
|
169
|
+
} else if (settings.formData) {
|
170
|
+
formData = [];
|
171
|
+
$.each(settings.formData, function (name, value) {
|
172
|
+
formData.push({name: name, value: value});
|
173
|
+
});
|
174
|
+
return formData;
|
175
|
+
}
|
176
|
+
return [];
|
177
|
+
},
|
178
|
+
|
179
|
+
isSameDomain = function (url) {
|
180
|
+
if (protocolRegExp.test(url)) {
|
181
|
+
var host = location.host,
|
182
|
+
indexStart = location.protocol.length + 2,
|
183
|
+
index = url.indexOf(host, indexStart),
|
184
|
+
pathIndex = index + host.length;
|
185
|
+
if ((index === indexStart || index === url.indexOf('@', indexStart) + 1) &&
|
186
|
+
(url.length === pathIndex || $.inArray(url.charAt(pathIndex), ['/', '?', '#']) !== -1)) {
|
187
|
+
return true;
|
188
|
+
}
|
189
|
+
return false;
|
190
|
+
}
|
191
|
+
return true;
|
192
|
+
},
|
193
|
+
|
194
|
+
nonMultipartUpload = function (file, xhr, sameDomain) {
|
195
|
+
if (sameDomain) {
|
196
|
+
xhr.setRequestHeader('X-File-Name', unescape(encodeURIComponent(file.name)));
|
197
|
+
}
|
198
|
+
xhr.setRequestHeader('Content-Type', file.type);
|
199
|
+
xhr.send(file);
|
200
|
+
},
|
201
|
+
|
202
|
+
formDataUpload = function (files, xhr, settings) {
|
203
|
+
var formData = new FormData(),
|
204
|
+
i;
|
205
|
+
$.each(getFormData(settings), function (index, field) {
|
206
|
+
formData.append(field.name, field.value);
|
207
|
+
});
|
208
|
+
for (i = 0; i < files.length; i += 1) {
|
209
|
+
formData.append(getFieldName(settings), files[i]);
|
210
|
+
}
|
211
|
+
xhr.send(formData);
|
212
|
+
},
|
213
|
+
|
214
|
+
loadFileContent = function (file, callBack) {
|
215
|
+
var fileReader = new FileReader();
|
216
|
+
fileReader.onload = function (e) {
|
217
|
+
file.content = e.target.result;
|
218
|
+
callBack();
|
219
|
+
};
|
220
|
+
fileReader.readAsBinaryString(file);
|
221
|
+
},
|
222
|
+
|
223
|
+
buildMultiPartFormData = function (boundary, files, filesFieldName, fields) {
|
224
|
+
var doubleDash = '--',
|
225
|
+
crlf = '\r\n',
|
226
|
+
formData = '';
|
227
|
+
$.each(fields, function (index, field) {
|
228
|
+
formData += doubleDash + boundary + crlf +
|
229
|
+
'Content-Disposition: form-data; name="' +
|
230
|
+
unescape(encodeURIComponent(field.name)) +
|
231
|
+
'"' + crlf + crlf +
|
232
|
+
unescape(encodeURIComponent(field.value)) + crlf;
|
233
|
+
});
|
234
|
+
$.each(files, function (index, file) {
|
235
|
+
formData += doubleDash + boundary + crlf +
|
236
|
+
'Content-Disposition: form-data; name="' +
|
237
|
+
unescape(encodeURIComponent(filesFieldName)) +
|
238
|
+
'"; filename="' + unescape(encodeURIComponent(file.name)) + '"' + crlf +
|
239
|
+
'Content-Type: ' + file.type + crlf + crlf +
|
240
|
+
file.content + crlf;
|
241
|
+
});
|
242
|
+
formData += doubleDash + boundary + doubleDash + crlf;
|
243
|
+
return formData;
|
244
|
+
},
|
245
|
+
|
246
|
+
fileReaderUpload = function (files, xhr, settings) {
|
247
|
+
var boundary = '----MultiPartFormBoundary' + (new Date()).getTime(),
|
248
|
+
loader,
|
249
|
+
i;
|
250
|
+
xhr.setRequestHeader('Content-Type', 'multipart/form-data; boundary=' + boundary);
|
251
|
+
loader = new MultiLoader(function () {
|
252
|
+
xhr.sendAsBinary(buildMultiPartFormData(
|
253
|
+
boundary,
|
254
|
+
files,
|
255
|
+
getFieldName(settings),
|
256
|
+
getFormData(settings)
|
257
|
+
));
|
258
|
+
}, files.length);
|
259
|
+
for (i = 0; i < files.length; i += 1) {
|
260
|
+
loadFileContent(files[i], loader.complete);
|
261
|
+
}
|
262
|
+
},
|
263
|
+
|
264
|
+
upload = function (files, index, xhr, settings) {
|
265
|
+
var url = getUrl(settings),
|
266
|
+
sameDomain = isSameDomain(url),
|
267
|
+
filesToUpload;
|
268
|
+
initUploadEventHandlers(files, index, xhr, settings);
|
269
|
+
xhr.open(getMethod(settings), url, true);
|
270
|
+
if (sameDomain) {
|
271
|
+
xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
|
272
|
+
} else if (settings.withCredentials) {
|
273
|
+
xhr.withCredentials = true;
|
274
|
+
}
|
275
|
+
if (!settings.multipart) {
|
276
|
+
nonMultipartUpload(files[index], xhr, sameDomain);
|
277
|
+
} else {
|
278
|
+
if (typeof index === num) {
|
279
|
+
filesToUpload = [files[index]];
|
280
|
+
} else {
|
281
|
+
filesToUpload = files;
|
282
|
+
}
|
283
|
+
if (typeof FormData !== undef) {
|
284
|
+
formDataUpload(filesToUpload, xhr, settings);
|
285
|
+
} else if (typeof FileReader !== undef) {
|
286
|
+
fileReaderUpload(filesToUpload, xhr, settings);
|
287
|
+
} else {
|
288
|
+
$.error('Browser does neither support FormData nor FileReader interface');
|
289
|
+
}
|
290
|
+
}
|
291
|
+
},
|
292
|
+
|
293
|
+
handleUpload = function (event, files, input, form, index) {
|
294
|
+
var xhr = new XMLHttpRequest(),
|
295
|
+
uploadSettings = $.extend({}, settings);
|
296
|
+
uploadSettings.fileInput = input;
|
297
|
+
uploadSettings.uploadForm = form;
|
298
|
+
if (typeof uploadSettings.initUpload === func) {
|
299
|
+
uploadSettings.initUpload(
|
300
|
+
event,
|
301
|
+
files,
|
302
|
+
index,
|
303
|
+
xhr,
|
304
|
+
uploadSettings,
|
305
|
+
function () {
|
306
|
+
upload(files, index, xhr, uploadSettings);
|
307
|
+
}
|
308
|
+
);
|
309
|
+
} else {
|
310
|
+
upload(files, index, xhr, uploadSettings);
|
311
|
+
}
|
312
|
+
},
|
313
|
+
|
314
|
+
handleFiles = function (event, files, input, form) {
|
315
|
+
var i;
|
316
|
+
if (settings.multiFileRequest) {
|
317
|
+
handleUpload(event, files, input, form);
|
318
|
+
} else {
|
319
|
+
for (i = 0; i < files.length; i += 1) {
|
320
|
+
handleUpload(event, files, input, form, i);
|
321
|
+
}
|
322
|
+
}
|
323
|
+
},
|
324
|
+
|
325
|
+
legacyUploadFormDataInit = function (input, form, settings) {
|
326
|
+
var formData = getFormData(settings);
|
327
|
+
form.find(':input').not(':disabled')
|
328
|
+
.attr('disabled', true)
|
329
|
+
.addClass(settings.namespace + '_disabled');
|
330
|
+
$.each(formData, function (index, field) {
|
331
|
+
$('<input type="hidden"/>')
|
332
|
+
.attr('name', field.name)
|
333
|
+
.val(field.value)
|
334
|
+
.addClass(settings.namespace + '_form_data')
|
335
|
+
.appendTo(form);
|
336
|
+
});
|
337
|
+
input
|
338
|
+
.attr('name', getFieldName(settings))
|
339
|
+
.appendTo(form);
|
340
|
+
},
|
341
|
+
|
342
|
+
legacyUploadFormDataReset = function (input, form, settings) {
|
343
|
+
input.detach();
|
344
|
+
form.find('.' + settings.namespace + '_disabled')
|
345
|
+
.removeAttr('disabled')
|
346
|
+
.removeClass(settings.namespace + '_disabled');
|
347
|
+
form.find('.' + settings.namespace + '_form_data').remove();
|
348
|
+
},
|
349
|
+
|
350
|
+
legacyUpload = function (input, form, iframe, settings) {
|
351
|
+
var originalAction = form.attr('action'),
|
352
|
+
originalMethod = form.attr('method'),
|
353
|
+
originalTarget = form.attr('target');
|
354
|
+
iframe
|
355
|
+
.unbind('abort')
|
356
|
+
.bind('abort', function (e) {
|
357
|
+
iframe.readyState = 0;
|
358
|
+
// javascript:false as iframe src prevents warning popups on HTTPS in IE6
|
359
|
+
// concat is used here to prevent the "Script URL" JSLint error:
|
360
|
+
iframe.unbind('load').attr('src', 'javascript'.concat(':false;'));
|
361
|
+
if (typeof settings.onAbort === func) {
|
362
|
+
settings.onAbort(e, [{name: input.val(), type: null, size: null}], 0, iframe, settings);
|
363
|
+
}
|
364
|
+
})
|
365
|
+
.unbind('load')
|
366
|
+
.bind('load', function (e) {
|
367
|
+
iframe.readyState = 4;
|
368
|
+
if (typeof settings.onLoad === func) {
|
369
|
+
settings.onLoad(e, [{name: input.val(), type: null, size: null}], 0, iframe, settings);
|
370
|
+
}
|
371
|
+
// Fix for IE endless progress bar activity bug (happens on form submits to iframe targets):
|
372
|
+
$('<iframe src="javascript:false;" style="display:none"></iframe>').appendTo(form).remove();
|
373
|
+
});
|
374
|
+
form
|
375
|
+
.attr('action', getUrl(settings))
|
376
|
+
.attr('method', getMethod(settings))
|
377
|
+
.attr('target', iframe.attr('name'));
|
378
|
+
legacyUploadFormDataInit(input, form, settings);
|
379
|
+
iframe.readyState = 2;
|
380
|
+
form.get(0).submit();
|
381
|
+
legacyUploadFormDataReset(input, form, settings);
|
382
|
+
form
|
383
|
+
.attr('action', originalAction)
|
384
|
+
.attr('method', originalMethod)
|
385
|
+
.attr('target', originalTarget);
|
386
|
+
},
|
387
|
+
|
388
|
+
handleLegacyUpload = function (event, input, form) {
|
389
|
+
// javascript:false as iframe src prevents warning popups on HTTPS in IE6:
|
390
|
+
var iframe = $('<iframe src="javascript:false;" style="display:none" name="iframe_' +
|
391
|
+
settings.namespace + '_' + (new Date()).getTime() + '"></iframe>'),
|
392
|
+
uploadSettings = $.extend({}, settings);
|
393
|
+
uploadSettings.fileInput = input;
|
394
|
+
uploadSettings.uploadForm = form;
|
395
|
+
iframe.readyState = 0;
|
396
|
+
iframe.abort = function () {
|
397
|
+
iframe.trigger('abort');
|
398
|
+
};
|
399
|
+
iframe.bind('load', function () {
|
400
|
+
iframe.unbind('load');
|
401
|
+
if (typeof uploadSettings.initUpload === func) {
|
402
|
+
uploadSettings.initUpload(
|
403
|
+
event,
|
404
|
+
[{name: input.val(), type: null, size: null}],
|
405
|
+
0,
|
406
|
+
iframe,
|
407
|
+
uploadSettings,
|
408
|
+
function () {
|
409
|
+
legacyUpload(input, form, iframe, uploadSettings);
|
410
|
+
}
|
411
|
+
);
|
412
|
+
} else {
|
413
|
+
legacyUpload(input, form, iframe, uploadSettings);
|
414
|
+
}
|
415
|
+
}).appendTo(form);
|
416
|
+
},
|
417
|
+
|
418
|
+
initUploadForm = function () {
|
419
|
+
uploadForm = (container.is('form') ? container : container.find('form'))
|
420
|
+
.filter(settings.uploadFormFilter);
|
421
|
+
},
|
422
|
+
|
423
|
+
initFileInput = function () {
|
424
|
+
fileInput = uploadForm.find('input:file')
|
425
|
+
.filter(settings.fileInputFilter);
|
426
|
+
},
|
427
|
+
|
428
|
+
replaceFileInput = function (input) {
|
429
|
+
var inputClone = input.clone(true);
|
430
|
+
$('<form/>').append(inputClone).get(0).reset();
|
431
|
+
input.after(inputClone).detach();
|
432
|
+
initFileInput();
|
433
|
+
};
|
434
|
+
|
435
|
+
this.onDocumentDragOver = function (e) {
|
436
|
+
if (typeof settings.onDocumentDragOver === func &&
|
437
|
+
settings.onDocumentDragOver(e) === false) {
|
438
|
+
return false;
|
439
|
+
}
|
440
|
+
e.preventDefault();
|
441
|
+
};
|
442
|
+
|
443
|
+
this.onDocumentDrop = function (e) {
|
444
|
+
if (typeof settings.onDocumentDrop === func &&
|
445
|
+
settings.onDocumentDrop(e) === false) {
|
446
|
+
return false;
|
447
|
+
}
|
448
|
+
e.preventDefault();
|
449
|
+
};
|
450
|
+
|
451
|
+
this.onDragOver = function (e) {
|
452
|
+
if (typeof settings.onDragOver === func &&
|
453
|
+
settings.onDragOver(e) === false) {
|
454
|
+
return false;
|
455
|
+
}
|
456
|
+
var dataTransfer = e.originalEvent.dataTransfer;
|
457
|
+
if (dataTransfer) {
|
458
|
+
dataTransfer.dropEffect = dataTransfer.effectAllowed = 'copy';
|
459
|
+
}
|
460
|
+
e.preventDefault();
|
461
|
+
};
|
462
|
+
|
463
|
+
this.onDrop = function (e) {
|
464
|
+
if (typeof settings.onDrop === func &&
|
465
|
+
settings.onDrop(e) === false) {
|
466
|
+
return false;
|
467
|
+
}
|
468
|
+
var dataTransfer = e.originalEvent.dataTransfer;
|
469
|
+
if (dataTransfer && dataTransfer.files && isXHRUploadCapable()) {
|
470
|
+
handleFiles(e, dataTransfer.files);
|
471
|
+
}
|
472
|
+
e.preventDefault();
|
473
|
+
};
|
474
|
+
|
475
|
+
this.onChange = function (e) {
|
476
|
+
if (typeof settings.onChange === func &&
|
477
|
+
settings.onChange(e) === false) {
|
478
|
+
return false;
|
479
|
+
}
|
480
|
+
var input = $(e.target),
|
481
|
+
form = $(e.target.form);
|
482
|
+
if (form.length === 1) {
|
483
|
+
input.data(defaultNamespace + '_form', form);
|
484
|
+
replaceFileInput(input);
|
485
|
+
} else {
|
486
|
+
form = input.data(defaultNamespace + '_form');
|
487
|
+
}
|
488
|
+
if (!settings.forceIframeUpload && e.target.files && isXHRUploadCapable()) {
|
489
|
+
handleFiles(e, e.target.files, input, form);
|
490
|
+
} else {
|
491
|
+
handleLegacyUpload(e, input, form);
|
492
|
+
}
|
493
|
+
};
|
494
|
+
|
495
|
+
this.init = function (options) {
|
496
|
+
if (options) {
|
497
|
+
$.extend(settings, options);
|
498
|
+
optionsReference = options;
|
499
|
+
}
|
500
|
+
initUploadForm();
|
501
|
+
initFileInput();
|
502
|
+
if (container.data(settings.namespace)) {
|
503
|
+
$.error('FileUpload with namespace "' + settings.namespace + '" already assigned to this element');
|
504
|
+
return;
|
505
|
+
}
|
506
|
+
container
|
507
|
+
.data(settings.namespace, fileUpload)
|
508
|
+
.addClass(settings.cssClass);
|
509
|
+
settings.dropZone.not(container).addClass(settings.cssClass);
|
510
|
+
initEventHandlers();
|
511
|
+
};
|
512
|
+
|
513
|
+
this.options = function (options) {
|
514
|
+
var oldCssClass,
|
515
|
+
oldDropZone,
|
516
|
+
uploadFormFilterUpdate,
|
517
|
+
fileInputFilterUpdate;
|
518
|
+
if (typeof options === undef) {
|
519
|
+
return $.extend({}, settings);
|
520
|
+
}
|
521
|
+
if (optionsReference) {
|
522
|
+
$.extend(optionsReference, options);
|
523
|
+
}
|
524
|
+
removeEventHandlers();
|
525
|
+
$.each(options, function (name, value) {
|
526
|
+
switch (name) {
|
527
|
+
case 'namespace':
|
528
|
+
$.error('The FileUpload namespace cannot be updated.');
|
529
|
+
return;
|
530
|
+
case 'uploadFormFilter':
|
531
|
+
uploadFormFilterUpdate = true;
|
532
|
+
fileInputFilterUpdate = true;
|
533
|
+
break;
|
534
|
+
case 'fileInputFilter':
|
535
|
+
fileInputFilterUpdate = true;
|
536
|
+
break;
|
537
|
+
case 'cssClass':
|
538
|
+
oldCssClass = settings.cssClass;
|
539
|
+
break;
|
540
|
+
case 'dropZone':
|
541
|
+
oldDropZone = settings.dropZone;
|
542
|
+
break;
|
543
|
+
}
|
544
|
+
settings[name] = value;
|
545
|
+
});
|
546
|
+
if (uploadFormFilterUpdate) {
|
547
|
+
initUploadForm();
|
548
|
+
}
|
549
|
+
if (fileInputFilterUpdate) {
|
550
|
+
initFileInput();
|
551
|
+
}
|
552
|
+
if (typeof oldCssClass !== undef) {
|
553
|
+
container
|
554
|
+
.removeClass(oldCssClass)
|
555
|
+
.addClass(settings.cssClass);
|
556
|
+
(oldDropZone ? oldDropZone : settings.dropZone).not(container)
|
557
|
+
.removeClass(oldCssClass);
|
558
|
+
settings.dropZone.not(container).addClass(settings.cssClass);
|
559
|
+
} else if (oldDropZone) {
|
560
|
+
oldDropZone.not(container).removeClass(settings.cssClass);
|
561
|
+
settings.dropZone.not(container).addClass(settings.cssClass);
|
562
|
+
}
|
563
|
+
initEventHandlers();
|
564
|
+
};
|
565
|
+
|
566
|
+
this.option = function (name, value) {
|
567
|
+
var options;
|
568
|
+
if (typeof value === undef) {
|
569
|
+
return settings[name];
|
570
|
+
}
|
571
|
+
options = {};
|
572
|
+
options[name] = value;
|
573
|
+
fileUpload.options(options);
|
574
|
+
};
|
575
|
+
|
576
|
+
this.destroy = function () {
|
577
|
+
removeEventHandlers();
|
578
|
+
container
|
579
|
+
.removeData(settings.namespace)
|
580
|
+
.removeClass(settings.cssClass);
|
581
|
+
settings.dropZone.not(container).removeClass(settings.cssClass);
|
582
|
+
};
|
583
|
+
};
|
584
|
+
|
585
|
+
methods = {
|
586
|
+
init : function (options) {
|
587
|
+
return this.each(function () {
|
588
|
+
(new FileUpload($(this))).init(options);
|
589
|
+
});
|
590
|
+
},
|
591
|
+
|
592
|
+
option: function (option, value, namespace) {
|
593
|
+
namespace = namespace ? namespace : defaultNamespace;
|
594
|
+
var fileUpload = $(this).data(namespace);
|
595
|
+
if (fileUpload) {
|
596
|
+
if (typeof option === 'string') {
|
597
|
+
return fileUpload.option(option, value);
|
598
|
+
}
|
599
|
+
return fileUpload.options(option);
|
600
|
+
} else {
|
601
|
+
$.error('No FileUpload with namespace "' + namespace + '" assigned to this element');
|
602
|
+
}
|
603
|
+
},
|
604
|
+
|
605
|
+
destroy : function (namespace) {
|
606
|
+
namespace = namespace ? namespace : defaultNamespace;
|
607
|
+
return this.each(function () {
|
608
|
+
var fileUpload = $(this).data(namespace);
|
609
|
+
if (fileUpload) {
|
610
|
+
fileUpload.destroy();
|
611
|
+
} else {
|
612
|
+
$.error('No FileUpload with namespace "' + namespace + '" assigned to this element');
|
613
|
+
}
|
614
|
+
});
|
615
|
+
|
616
|
+
}
|
617
|
+
};
|
618
|
+
|
619
|
+
$.fn.fileUpload = function (method) {
|
620
|
+
if (methods[method]) {
|
621
|
+
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
|
622
|
+
} else if (typeof method === 'object' || !method) {
|
623
|
+
return methods.init.apply(this, arguments);
|
624
|
+
} else {
|
625
|
+
$.error('Method ' + method + ' does not exist on jQuery.fileUpload');
|
626
|
+
}
|
627
|
+
};
|
628
|
+
|
629
|
+
}(jQuery));
|
Binary file
|
@@ -19,7 +19,6 @@ table.index .size {
|
|
19
19
|
|
20
20
|
#assets .icon {
|
21
21
|
display: block;
|
22
|
-
float: left;
|
23
22
|
text-align: center;
|
24
23
|
background: #ccc;
|
25
24
|
text-transform: uppercase;
|
@@ -36,6 +35,7 @@ table#assets .icon, table#assets .thumbnail {
|
|
36
35
|
|
37
36
|
table#assets .icon {
|
38
37
|
font-size: 75%;
|
38
|
+
float: left;
|
39
39
|
}
|
40
40
|
|
41
41
|
#assets, #assets li {
|
@@ -46,6 +46,7 @@ table#assets .icon {
|
|
46
46
|
}
|
47
47
|
|
48
48
|
#assets li {
|
49
|
+
background: #ccc;
|
49
50
|
float: left;
|
50
51
|
margin-right: 1px;
|
51
52
|
margin-bottom: 1px;
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: radiant-assets-extension
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 5
|
10
|
+
version: 0.0.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Gerrit Kaiser
|
@@ -88,6 +88,11 @@ files:
|
|
88
88
|
- lib/radiant-assets-extension/s3_store.rb
|
89
89
|
- lib/radiant-assets-extension/version.rb
|
90
90
|
- lib/tasks/assets_extension_tasks.rake
|
91
|
+
- public/jquery.fileupload/.gitignore
|
92
|
+
- public/jquery.fileupload/jquery.fileupload-ui.css
|
93
|
+
- public/jquery.fileupload/jquery.fileupload-ui.js
|
94
|
+
- public/jquery.fileupload/jquery.fileupload.js
|
95
|
+
- public/jquery.fileupload/pbar-ani.gif
|
91
96
|
- public/stylesheets/admin/extensions/assets/assets.css
|
92
97
|
- radiant-assets-extension.gemspec
|
93
98
|
- spec/spec.opts
|
@@ -96,7 +101,7 @@ has_rdoc: true
|
|
96
101
|
homepage: http://ext.radiantcms.org/extensions/269-assets
|
97
102
|
licenses: []
|
98
103
|
|
99
|
-
post_install_message: "\n Add this to your radiant project with:\n config.gem 'radiant-assets-extension', :version => '0.0.
|
104
|
+
post_install_message: "\n Add this to your radiant project with:\n config.gem 'radiant-assets-extension', :version => '0.0.5'\n "
|
100
105
|
rdoc_options: []
|
101
106
|
|
102
107
|
require_paths:
|