rails_admin_uploader 1.0.0
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.
- checksums.yaml +7 -0
- data/.gitignore +9 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +21 -0
- data/README.md +78 -0
- data/Rakefile +1 -0
- data/app/assets/images/rails_admin_uploader/loading.gif +0 -0
- data/app/assets/images/rails_admin_uploader/progressbar.gif +0 -0
- data/app/assets/javascripts/rails_admin_uploader.coffee +261 -0
- data/app/assets/javascripts/rails_admin_uploader/canvas-to-blob.js +95 -0
- data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload-audio.js +112 -0
- data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload-image.js +321 -0
- data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload-process.js +175 -0
- data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload-ui.js +710 -0
- data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload-validate.js +122 -0
- data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload-video.js +112 -0
- data/app/assets/javascripts/rails_admin_uploader/jquery.fileupload.js +1477 -0
- data/app/assets/javascripts/rails_admin_uploader/jquery.iframe-transport.js +217 -0
- data/app/assets/javascripts/rails_admin_uploader/load-image.all.min.js +1 -0
- data/app/assets/javascripts/rails_admin_uploader/tmpl.js +87 -0
- data/app/assets/stylesheets/rails_admin_uploader.sass +2 -0
- data/app/assets/stylesheets/rails_admin_uploader/jquery.fileupload-ui.scss +57 -0
- data/app/assets/stylesheets/rails_admin_uploader/jquery.fileupload.scss +37 -0
- data/app/controllers/rails_admin_uploader/attachments_controller.rb +94 -0
- data/app/views/rails_admin/main/_rails_admin_uploader.html.haml +16 -0
- data/bin/console +14 -0
- data/bin/setup +7 -0
- data/config/locales/ru.yml +6 -0
- data/config/routes.rb +8 -0
- data/lib/rails_admin_uploader.rb +15 -0
- data/lib/rails_admin_uploader/asset.rb +19 -0
- data/lib/rails_admin_uploader/base.rb +50 -0
- data/lib/rails_admin_uploader/engine.rb +6 -0
- data/lib/rails_admin_uploader/field.rb +12 -0
- data/lib/rails_admin_uploader/version.rb +3 -0
- data/rails_admin_uploader.gemspec +24 -0
- metadata +107 -0
@@ -0,0 +1,217 @@
|
|
1
|
+
/*
|
2
|
+
* jQuery Iframe Transport Plugin
|
3
|
+
* https://github.com/blueimp/jQuery-File-Upload
|
4
|
+
*
|
5
|
+
* Copyright 2011, Sebastian Tschan
|
6
|
+
* https://blueimp.net
|
7
|
+
*
|
8
|
+
* Licensed under the MIT license:
|
9
|
+
* http://www.opensource.org/licenses/MIT
|
10
|
+
*/
|
11
|
+
|
12
|
+
/* global define, require, window, document */
|
13
|
+
|
14
|
+
(function (factory) {
|
15
|
+
'use strict';
|
16
|
+
if (typeof define === 'function' && define.amd) {
|
17
|
+
// Register as an anonymous AMD module:
|
18
|
+
define(['jquery'], factory);
|
19
|
+
} else if (typeof exports === 'object') {
|
20
|
+
// Node/CommonJS:
|
21
|
+
factory(require('jquery'));
|
22
|
+
} else {
|
23
|
+
// Browser globals:
|
24
|
+
factory(window.jQuery);
|
25
|
+
}
|
26
|
+
}(function ($) {
|
27
|
+
'use strict';
|
28
|
+
|
29
|
+
// Helper variable to create unique names for the transport iframes:
|
30
|
+
var counter = 0;
|
31
|
+
|
32
|
+
// The iframe transport accepts four additional options:
|
33
|
+
// options.fileInput: a jQuery collection of file input fields
|
34
|
+
// options.paramName: the parameter name for the file form data,
|
35
|
+
// overrides the name property of the file input field(s),
|
36
|
+
// can be a string or an array of strings.
|
37
|
+
// options.formData: an array of objects with name and value properties,
|
38
|
+
// equivalent to the return data of .serializeArray(), e.g.:
|
39
|
+
// [{name: 'a', value: 1}, {name: 'b', value: 2}]
|
40
|
+
// options.initialIframeSrc: the URL of the initial iframe src,
|
41
|
+
// by default set to "javascript:false;"
|
42
|
+
$.ajaxTransport('iframe', function (options) {
|
43
|
+
if (options.async) {
|
44
|
+
// javascript:false as initial iframe src
|
45
|
+
// prevents warning popups on HTTPS in IE6:
|
46
|
+
/*jshint scripturl: true */
|
47
|
+
var initialIframeSrc = options.initialIframeSrc || 'javascript:false;',
|
48
|
+
/*jshint scripturl: false */
|
49
|
+
form,
|
50
|
+
iframe,
|
51
|
+
addParamChar;
|
52
|
+
return {
|
53
|
+
send: function (_, completeCallback) {
|
54
|
+
form = $('<form style="display:none;"></form>');
|
55
|
+
form.attr('accept-charset', options.formAcceptCharset);
|
56
|
+
addParamChar = /\?/.test(options.url) ? '&' : '?';
|
57
|
+
// XDomainRequest only supports GET and POST:
|
58
|
+
if (options.type === 'DELETE') {
|
59
|
+
options.url = options.url + addParamChar + '_method=DELETE';
|
60
|
+
options.type = 'POST';
|
61
|
+
} else if (options.type === 'PUT') {
|
62
|
+
options.url = options.url + addParamChar + '_method=PUT';
|
63
|
+
options.type = 'POST';
|
64
|
+
} else if (options.type === 'PATCH') {
|
65
|
+
options.url = options.url + addParamChar + '_method=PATCH';
|
66
|
+
options.type = 'POST';
|
67
|
+
}
|
68
|
+
// IE versions below IE8 cannot set the name property of
|
69
|
+
// elements that have already been added to the DOM,
|
70
|
+
// so we set the name along with the iframe HTML markup:
|
71
|
+
counter += 1;
|
72
|
+
iframe = $(
|
73
|
+
'<iframe src="' + initialIframeSrc +
|
74
|
+
'" name="iframe-transport-' + counter + '"></iframe>'
|
75
|
+
).bind('load', function () {
|
76
|
+
var fileInputClones,
|
77
|
+
paramNames = $.isArray(options.paramName) ?
|
78
|
+
options.paramName : [options.paramName];
|
79
|
+
iframe
|
80
|
+
.unbind('load')
|
81
|
+
.bind('load', function () {
|
82
|
+
var response;
|
83
|
+
// Wrap in a try/catch block to catch exceptions thrown
|
84
|
+
// when trying to access cross-domain iframe contents:
|
85
|
+
try {
|
86
|
+
response = iframe.contents();
|
87
|
+
// Google Chrome and Firefox do not throw an
|
88
|
+
// exception when calling iframe.contents() on
|
89
|
+
// cross-domain requests, so we unify the response:
|
90
|
+
if (!response.length || !response[0].firstChild) {
|
91
|
+
throw new Error();
|
92
|
+
}
|
93
|
+
} catch (e) {
|
94
|
+
response = undefined;
|
95
|
+
}
|
96
|
+
// The complete callback returns the
|
97
|
+
// iframe content document as response object:
|
98
|
+
completeCallback(
|
99
|
+
200,
|
100
|
+
'success',
|
101
|
+
{'iframe': response}
|
102
|
+
);
|
103
|
+
// Fix for IE endless progress bar activity bug
|
104
|
+
// (happens on form submits to iframe targets):
|
105
|
+
$('<iframe src="' + initialIframeSrc + '"></iframe>')
|
106
|
+
.appendTo(form);
|
107
|
+
window.setTimeout(function () {
|
108
|
+
// Removing the form in a setTimeout call
|
109
|
+
// allows Chrome's developer tools to display
|
110
|
+
// the response result
|
111
|
+
form.remove();
|
112
|
+
}, 0);
|
113
|
+
});
|
114
|
+
form
|
115
|
+
.prop('target', iframe.prop('name'))
|
116
|
+
.prop('action', options.url)
|
117
|
+
.prop('method', options.type);
|
118
|
+
if (options.formData) {
|
119
|
+
$.each(options.formData, function (index, field) {
|
120
|
+
$('<input type="hidden"/>')
|
121
|
+
.prop('name', field.name)
|
122
|
+
.val(field.value)
|
123
|
+
.appendTo(form);
|
124
|
+
});
|
125
|
+
}
|
126
|
+
if (options.fileInput && options.fileInput.length &&
|
127
|
+
options.type === 'POST') {
|
128
|
+
fileInputClones = options.fileInput.clone();
|
129
|
+
// Insert a clone for each file input field:
|
130
|
+
options.fileInput.after(function (index) {
|
131
|
+
return fileInputClones[index];
|
132
|
+
});
|
133
|
+
if (options.paramName) {
|
134
|
+
options.fileInput.each(function (index) {
|
135
|
+
$(this).prop(
|
136
|
+
'name',
|
137
|
+
paramNames[index] || options.paramName
|
138
|
+
);
|
139
|
+
});
|
140
|
+
}
|
141
|
+
// Appending the file input fields to the hidden form
|
142
|
+
// removes them from their original location:
|
143
|
+
form
|
144
|
+
.append(options.fileInput)
|
145
|
+
.prop('enctype', 'multipart/form-data')
|
146
|
+
// enctype must be set as encoding for IE:
|
147
|
+
.prop('encoding', 'multipart/form-data');
|
148
|
+
// Remove the HTML5 form attribute from the input(s):
|
149
|
+
options.fileInput.removeAttr('form');
|
150
|
+
}
|
151
|
+
form.submit();
|
152
|
+
// Insert the file input fields at their original location
|
153
|
+
// by replacing the clones with the originals:
|
154
|
+
if (fileInputClones && fileInputClones.length) {
|
155
|
+
options.fileInput.each(function (index, input) {
|
156
|
+
var clone = $(fileInputClones[index]);
|
157
|
+
// Restore the original name and form properties:
|
158
|
+
$(input)
|
159
|
+
.prop('name', clone.prop('name'))
|
160
|
+
.attr('form', clone.attr('form'));
|
161
|
+
clone.replaceWith(input);
|
162
|
+
});
|
163
|
+
}
|
164
|
+
});
|
165
|
+
form.append(iframe).appendTo(document.body);
|
166
|
+
},
|
167
|
+
abort: function () {
|
168
|
+
if (iframe) {
|
169
|
+
// javascript:false as iframe src aborts the request
|
170
|
+
// and prevents warning popups on HTTPS in IE6.
|
171
|
+
// concat is used to avoid the "Script URL" JSLint error:
|
172
|
+
iframe
|
173
|
+
.unbind('load')
|
174
|
+
.prop('src', initialIframeSrc);
|
175
|
+
}
|
176
|
+
if (form) {
|
177
|
+
form.remove();
|
178
|
+
}
|
179
|
+
}
|
180
|
+
};
|
181
|
+
}
|
182
|
+
});
|
183
|
+
|
184
|
+
// The iframe transport returns the iframe content document as response.
|
185
|
+
// The following adds converters from iframe to text, json, html, xml
|
186
|
+
// and script.
|
187
|
+
// Please note that the Content-Type for JSON responses has to be text/plain
|
188
|
+
// or text/html, if the browser doesn't include application/json in the
|
189
|
+
// Accept header, else IE will show a download dialog.
|
190
|
+
// The Content-Type for XML responses on the other hand has to be always
|
191
|
+
// application/xml or text/xml, so IE properly parses the XML response.
|
192
|
+
// See also
|
193
|
+
// https://github.com/blueimp/jQuery-File-Upload/wiki/Setup#content-type-negotiation
|
194
|
+
$.ajaxSetup({
|
195
|
+
converters: {
|
196
|
+
'iframe text': function (iframe) {
|
197
|
+
return iframe && $(iframe[0].body).text();
|
198
|
+
},
|
199
|
+
'iframe json': function (iframe) {
|
200
|
+
return iframe && $.parseJSON($(iframe[0].body).text());
|
201
|
+
},
|
202
|
+
'iframe html': function (iframe) {
|
203
|
+
return iframe && $(iframe[0].body).html();
|
204
|
+
},
|
205
|
+
'iframe xml': function (iframe) {
|
206
|
+
var xmlDoc = iframe && iframe[0];
|
207
|
+
return xmlDoc && $.isXMLDoc(xmlDoc) ? xmlDoc :
|
208
|
+
$.parseXML((xmlDoc.XMLDocument && xmlDoc.XMLDocument.xml) ||
|
209
|
+
$(xmlDoc.body).html());
|
210
|
+
},
|
211
|
+
'iframe script': function (iframe) {
|
212
|
+
return iframe && $.globalEval($(iframe[0].body).text());
|
213
|
+
}
|
214
|
+
}
|
215
|
+
});
|
216
|
+
|
217
|
+
}));
|
@@ -0,0 +1 @@
|
|
1
|
+
!function(a){"use strict";var b=function(a,c,d){var e,f,g=document.createElement("img");if(g.onerror=c,g.onload=function(){!f||d&&d.noRevoke||b.revokeObjectURL(f),c&&c(b.scale(g,d))},b.isInstanceOf("Blob",a)||b.isInstanceOf("File",a))e=f=b.createObjectURL(a),g._type=a.type;else{if("string"!=typeof a)return!1;e=a,d&&d.crossOrigin&&(g.crossOrigin=d.crossOrigin)}return e?(g.src=e,g):b.readFile(a,function(a){var b=a.target;b&&b.result?g.src=b.result:c&&c(a)})},c=window.createObjectURL&&window||window.URL&&URL.revokeObjectURL&&URL||window.webkitURL&&webkitURL;b.isInstanceOf=function(a,b){return Object.prototype.toString.call(b)==="[object "+a+"]"},b.transformCoordinates=function(){},b.getTransformedOptions=function(a,b){var c,d,e,f,g=b.aspectRatio;if(!g)return b;c={};for(d in b)b.hasOwnProperty(d)&&(c[d]=b[d]);return c.crop=!0,e=a.naturalWidth||a.width,f=a.naturalHeight||a.height,e/f>g?(c.maxWidth=f*g,c.maxHeight=f):(c.maxWidth=e,c.maxHeight=e/g),c},b.renderImageToCanvas=function(a,b,c,d,e,f,g,h,i,j){return a.getContext("2d").drawImage(b,c,d,e,f,g,h,i,j),a},b.hasCanvasOption=function(a){return a.canvas||a.crop||a.aspectRatio},b.scale=function(a,c){c=c||{};var d,e,f,g,h,i,j,k,l,m=document.createElement("canvas"),n=a.getContext||b.hasCanvasOption(c)&&m.getContext,o=a.naturalWidth||a.width,p=a.naturalHeight||a.height,q=o,r=p,s=function(){var a=Math.max((f||q)/q,(g||r)/r);a>1&&(q*=a,r*=a)},t=function(){var a=Math.min((d||q)/q,(e||r)/r);1>a&&(q*=a,r*=a)};return n&&(c=b.getTransformedOptions(a,c),j=c.left||0,k=c.top||0,c.sourceWidth?(h=c.sourceWidth,void 0!==c.right&&void 0===c.left&&(j=o-h-c.right)):h=o-j-(c.right||0),c.sourceHeight?(i=c.sourceHeight,void 0!==c.bottom&&void 0===c.top&&(k=p-i-c.bottom)):i=p-k-(c.bottom||0),q=h,r=i),d=c.maxWidth,e=c.maxHeight,f=c.minWidth,g=c.minHeight,n&&d&&e&&c.crop?(q=d,r=e,l=h/i-d/e,0>l?(i=e*h/d,void 0===c.top&&void 0===c.bottom&&(k=(p-i)/2)):l>0&&(h=d*i/e,void 0===c.left&&void 0===c.right&&(j=(o-h)/2))):((c.contain||c.cover)&&(f=d=d||f,g=e=e||g),c.cover?(t(),s()):(s(),t())),n?(m.width=q,m.height=r,b.transformCoordinates(m,c),b.renderImageToCanvas(m,a,j,k,h,i,0,0,q,r)):(a.width=q,a.height=r,a)},b.createObjectURL=function(a){return c?c.createObjectURL(a):!1},b.revokeObjectURL=function(a){return c?c.revokeObjectURL(a):!1},b.readFile=function(a,b,c){if(window.FileReader){var d=new FileReader;if(d.onload=d.onerror=b,c=c||"readAsDataURL",d[c])return d[c](a),d}return!1},"function"==typeof define&&define.amd?define(function(){return b}):a.loadImage=b}(window),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image"],a):a(window.loadImage)}(function(a){"use strict";if(window.navigator&&window.navigator.platform&&/iP(hone|od|ad)/.test(window.navigator.platform)){var b=a.renderImageToCanvas;a.detectSubsampling=function(a){var b,c;return a.width*a.height>1048576?(b=document.createElement("canvas"),b.width=b.height=1,c=b.getContext("2d"),c.drawImage(a,-a.width+1,0),0===c.getImageData(0,0,1,1).data[3]):!1},a.detectVerticalSquash=function(a,b){var c,d,e,f,g,h=a.naturalHeight||a.height,i=document.createElement("canvas"),j=i.getContext("2d");for(b&&(h/=2),i.width=1,i.height=h,j.drawImage(a,0,0),c=j.getImageData(0,0,1,h).data,d=0,e=h,f=h;f>d;)g=c[4*(f-1)+3],0===g?e=f:d=f,f=e+d>>1;return f/h||1},a.renderImageToCanvas=function(c,d,e,f,g,h,i,j,k,l){if("image/jpeg"===d._type){var m,n,o,p,q=c.getContext("2d"),r=document.createElement("canvas"),s=1024,t=r.getContext("2d");if(r.width=s,r.height=s,q.save(),m=a.detectSubsampling(d),m&&(e/=2,f/=2,g/=2,h/=2),n=a.detectVerticalSquash(d,m),m||1!==n){for(f*=n,k=Math.ceil(s*k/g),l=Math.ceil(s*l/h/n),j=0,p=0;h>p;){for(i=0,o=0;g>o;)t.clearRect(0,0,s,s),t.drawImage(d,e,f,g,h,-o,-p,g,h),q.drawImage(r,0,0,s,s,i,j,k,l),o+=s,i+=k;p+=s,j+=l}return q.restore(),c}}return b(c,d,e,f,g,h,i,j,k,l)}}}),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image"],a):a(window.loadImage)}(function(a){"use strict";var b=a.hasCanvasOption,c=a.transformCoordinates,d=a.getTransformedOptions;a.hasCanvasOption=function(c){return b.call(a,c)||c.orientation},a.transformCoordinates=function(b,d){c.call(a,b,d);var e=b.getContext("2d"),f=b.width,g=b.height,h=d.orientation;if(h&&!(h>8))switch(h>4&&(b.width=g,b.height=f),h){case 2:e.translate(f,0),e.scale(-1,1);break;case 3:e.translate(f,g),e.rotate(Math.PI);break;case 4:e.translate(0,g),e.scale(1,-1);break;case 5:e.rotate(.5*Math.PI),e.scale(1,-1);break;case 6:e.rotate(.5*Math.PI),e.translate(0,-g);break;case 7:e.rotate(.5*Math.PI),e.translate(f,-g),e.scale(-1,1);break;case 8:e.rotate(-.5*Math.PI),e.translate(-f,0)}},a.getTransformedOptions=function(b,c){var e,f,g=d.call(a,b,c),h=g.orientation;if(!h||h>8||1===h)return g;e={};for(f in g)g.hasOwnProperty(f)&&(e[f]=g[f]);switch(g.orientation){case 2:e.left=g.right,e.right=g.left;break;case 3:e.left=g.right,e.top=g.bottom,e.right=g.left,e.bottom=g.top;break;case 4:e.top=g.bottom,e.bottom=g.top;break;case 5:e.left=g.top,e.top=g.left,e.right=g.bottom,e.bottom=g.right;break;case 6:e.left=g.top,e.top=g.right,e.right=g.bottom,e.bottom=g.left;break;case 7:e.left=g.bottom,e.top=g.right,e.right=g.top,e.bottom=g.left;break;case 8:e.left=g.bottom,e.top=g.left,e.right=g.top,e.bottom=g.right}return g.orientation>4&&(e.maxWidth=g.maxHeight,e.maxHeight=g.maxWidth,e.minWidth=g.minHeight,e.minHeight=g.minWidth,e.sourceWidth=g.sourceHeight,e.sourceHeight=g.sourceWidth),e}}),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image"],a):a(window.loadImage)}(function(a){"use strict";var b=window.Blob&&(Blob.prototype.slice||Blob.prototype.webkitSlice||Blob.prototype.mozSlice);a.blobSlice=b&&function(){var a=this.slice||this.webkitSlice||this.mozSlice;return a.apply(this,arguments)},a.metaDataParsers={jpeg:{65505:[]}},a.parseMetaData=function(b,c,d){d=d||{};var e=this,f=d.maxMetaDataSize||262144,g={},h=!(window.DataView&&b&&b.size>=12&&"image/jpeg"===b.type&&a.blobSlice);(h||!a.readFile(a.blobSlice.call(b,0,f),function(b){if(b.target.error)return console.log(b.target.error),void c(g);var f,h,i,j,k=b.target.result,l=new DataView(k),m=2,n=l.byteLength-4,o=m;if(65496===l.getUint16(0)){for(;n>m&&(f=l.getUint16(m),f>=65504&&65519>=f||65534===f);){if(h=l.getUint16(m+2)+2,m+h>l.byteLength){console.log("Invalid meta data: Invalid segment size.");break}if(i=a.metaDataParsers.jpeg[f])for(j=0;j<i.length;j+=1)i[j].call(e,l,m,h,g,d);m+=h,o=m}!d.disableImageHead&&o>6&&(g.imageHead=k.slice?k.slice(0,o):new Uint8Array(k).subarray(0,o))}else console.log("Invalid JPEG file: Missing JPEG marker.");c(g)},"readAsArrayBuffer"))&&c(g)}}),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image","load-image-meta"],a):a(window.loadImage)}(function(a){"use strict";a.ExifMap=function(){return this},a.ExifMap.prototype.map={Orientation:274},a.ExifMap.prototype.get=function(a){return this[a]||this[this.map[a]]},a.getExifThumbnail=function(a,b,c){var d,e,f;if(!c||b+c>a.byteLength)return void console.log("Invalid Exif data: Invalid thumbnail data.");for(d=[],e=0;c>e;e+=1)f=a.getUint8(b+e),d.push((16>f?"0":"")+f.toString(16));return"data:image/jpeg,%"+d.join("%")},a.exifTagTypes={1:{getValue:function(a,b){return a.getUint8(b)},size:1},2:{getValue:function(a,b){return String.fromCharCode(a.getUint8(b))},size:1,ascii:!0},3:{getValue:function(a,b,c){return a.getUint16(b,c)},size:2},4:{getValue:function(a,b,c){return a.getUint32(b,c)},size:4},5:{getValue:function(a,b,c){return a.getUint32(b,c)/a.getUint32(b+4,c)},size:8},9:{getValue:function(a,b,c){return a.getInt32(b,c)},size:4},10:{getValue:function(a,b,c){return a.getInt32(b,c)/a.getInt32(b+4,c)},size:8}},a.exifTagTypes[7]=a.exifTagTypes[1],a.getExifValue=function(b,c,d,e,f,g){var h,i,j,k,l,m,n=a.exifTagTypes[e];if(!n)return void console.log("Invalid Exif data: Invalid tag type.");if(h=n.size*f,i=h>4?c+b.getUint32(d+8,g):d+8,i+h>b.byteLength)return void console.log("Invalid Exif data: Invalid data offset.");if(1===f)return n.getValue(b,i,g);for(j=[],k=0;f>k;k+=1)j[k]=n.getValue(b,i+k*n.size,g);if(n.ascii){for(l="",k=0;k<j.length&&(m=j[k],"\x00"!==m);k+=1)l+=m;return l}return j},a.parseExifTag=function(b,c,d,e,f){var g=b.getUint16(d,e);f.exif[g]=a.getExifValue(b,c,d,b.getUint16(d+2,e),b.getUint32(d+4,e),e)},a.parseExifTags=function(a,b,c,d,e){var f,g,h;if(c+6>a.byteLength)return void console.log("Invalid Exif data: Invalid directory offset.");if(f=a.getUint16(c,d),g=c+2+12*f,g+4>a.byteLength)return void console.log("Invalid Exif data: Invalid directory size.");for(h=0;f>h;h+=1)this.parseExifTag(a,b,c+2+12*h,d,e);return a.getUint32(g,d)},a.parseExifData=function(b,c,d,e,f){if(!f.disableExif){var g,h,i,j=c+10;if(1165519206===b.getUint32(c+4)){if(j+8>b.byteLength)return void console.log("Invalid Exif data: Invalid segment size.");if(0!==b.getUint16(c+8))return void console.log("Invalid Exif data: Missing byte alignment offset.");switch(b.getUint16(j)){case 18761:g=!0;break;case 19789:g=!1;break;default:return void console.log("Invalid Exif data: Invalid byte alignment marker.")}if(42!==b.getUint16(j+2,g))return void console.log("Invalid Exif data: Missing TIFF marker.");h=b.getUint32(j+4,g),e.exif=new a.ExifMap,h=a.parseExifTags(b,j,j+h,g,e),h&&!f.disableExifThumbnail&&(i={exif:{}},h=a.parseExifTags(b,j,j+h,g,i),i.exif[513]&&(e.exif.Thumbnail=a.getExifThumbnail(b,j+i.exif[513],i.exif[514]))),e.exif[34665]&&!f.disableExifSub&&a.parseExifTags(b,j,j+e.exif[34665],g,e),e.exif[34853]&&!f.disableExifGps&&a.parseExifTags(b,j,j+e.exif[34853],g,e)}}},a.metaDataParsers.jpeg[65505].push(a.parseExifData)}),function(a){"use strict";"function"==typeof define&&define.amd?define(["load-image","load-image-exif"],a):a(window.loadImage)}(function(a){"use strict";a.ExifMap.prototype.tags={256:"ImageWidth",257:"ImageHeight",34665:"ExifIFDPointer",34853:"GPSInfoIFDPointer",40965:"InteroperabilityIFDPointer",258:"BitsPerSample",259:"Compression",262:"PhotometricInterpretation",274:"Orientation",277:"SamplesPerPixel",284:"PlanarConfiguration",530:"YCbCrSubSampling",531:"YCbCrPositioning",282:"XResolution",283:"YResolution",296:"ResolutionUnit",273:"StripOffsets",278:"RowsPerStrip",279:"StripByteCounts",513:"JPEGInterchangeFormat",514:"JPEGInterchangeFormatLength",301:"TransferFunction",318:"WhitePoint",319:"PrimaryChromaticities",529:"YCbCrCoefficients",532:"ReferenceBlackWhite",306:"DateTime",270:"ImageDescription",271:"Make",272:"Model",305:"Software",315:"Artist",33432:"Copyright",36864:"ExifVersion",40960:"FlashpixVersion",40961:"ColorSpace",40962:"PixelXDimension",40963:"PixelYDimension",42240:"Gamma",37121:"ComponentsConfiguration",37122:"CompressedBitsPerPixel",37500:"MakerNote",37510:"UserComment",40964:"RelatedSoundFile",36867:"DateTimeOriginal",36868:"DateTimeDigitized",37520:"SubSecTime",37521:"SubSecTimeOriginal",37522:"SubSecTimeDigitized",33434:"ExposureTime",33437:"FNumber",34850:"ExposureProgram",34852:"SpectralSensitivity",34855:"PhotographicSensitivity",34856:"OECF",34864:"SensitivityType",34865:"StandardOutputSensitivity",34866:"RecommendedExposureIndex",34867:"ISOSpeed",34868:"ISOSpeedLatitudeyyy",34869:"ISOSpeedLatitudezzz",37377:"ShutterSpeedValue",37378:"ApertureValue",37379:"BrightnessValue",37380:"ExposureBias",37381:"MaxApertureValue",37382:"SubjectDistance",37383:"MeteringMode",37384:"LightSource",37385:"Flash",37396:"SubjectArea",37386:"FocalLength",41483:"FlashEnergy",41484:"SpatialFrequencyResponse",41486:"FocalPlaneXResolution",41487:"FocalPlaneYResolution",41488:"FocalPlaneResolutionUnit",41492:"SubjectLocation",41493:"ExposureIndex",41495:"SensingMethod",41728:"FileSource",41729:"SceneType",41730:"CFAPattern",41985:"CustomRendered",41986:"ExposureMode",41987:"WhiteBalance",41988:"DigitalZoomRatio",41989:"FocalLengthIn35mmFilm",41990:"SceneCaptureType",41991:"GainControl",41992:"Contrast",41993:"Saturation",41994:"Sharpness",41995:"DeviceSettingDescription",41996:"SubjectDistanceRange",42016:"ImageUniqueID",42032:"CameraOwnerName",42033:"BodySerialNumber",42034:"LensSpecification",42035:"LensMake",42036:"LensModel",42037:"LensSerialNumber",0:"GPSVersionID",1:"GPSLatitudeRef",2:"GPSLatitude",3:"GPSLongitudeRef",4:"GPSLongitude",5:"GPSAltitudeRef",6:"GPSAltitude",7:"GPSTimeStamp",8:"GPSSatellites",9:"GPSStatus",10:"GPSMeasureMode",11:"GPSDOP",12:"GPSSpeedRef",13:"GPSSpeed",14:"GPSTrackRef",15:"GPSTrack",16:"GPSImgDirectionRef",17:"GPSImgDirection",18:"GPSMapDatum",19:"GPSDestLatitudeRef",20:"GPSDestLatitude",21:"GPSDestLongitudeRef",22:"GPSDestLongitude",23:"GPSDestBearingRef",24:"GPSDestBearing",25:"GPSDestDistanceRef",26:"GPSDestDistance",27:"GPSProcessingMethod",28:"GPSAreaInformation",29:"GPSDateStamp",30:"GPSDifferential",31:"GPSHPositioningError"},a.ExifMap.prototype.stringValues={ExposureProgram:{0:"Undefined",1:"Manual",2:"Normal program",3:"Aperture priority",4:"Shutter priority",5:"Creative program",6:"Action program",7:"Portrait mode",8:"Landscape mode"},MeteringMode:{0:"Unknown",1:"Average",2:"CenterWeightedAverage",3:"Spot",4:"MultiSpot",5:"Pattern",6:"Partial",255:"Other"},LightSource:{0:"Unknown",1:"Daylight",2:"Fluorescent",3:"Tungsten (incandescent light)",4:"Flash",9:"Fine weather",10:"Cloudy weather",11:"Shade",12:"Daylight fluorescent (D 5700 - 7100K)",13:"Day white fluorescent (N 4600 - 5400K)",14:"Cool white fluorescent (W 3900 - 4500K)",15:"White fluorescent (WW 3200 - 3700K)",17:"Standard light A",18:"Standard light B",19:"Standard light C",20:"D55",21:"D65",22:"D75",23:"D50",24:"ISO studio tungsten",255:"Other"},Flash:{0:"Flash did not fire",1:"Flash fired",5:"Strobe return light not detected",7:"Strobe return light detected",9:"Flash fired, compulsory flash mode",13:"Flash fired, compulsory flash mode, return light not detected",15:"Flash fired, compulsory flash mode, return light detected",16:"Flash did not fire, compulsory flash mode",24:"Flash did not fire, auto mode",25:"Flash fired, auto mode",29:"Flash fired, auto mode, return light not detected",31:"Flash fired, auto mode, return light detected",32:"No flash function",65:"Flash fired, red-eye reduction mode",69:"Flash fired, red-eye reduction mode, return light not detected",71:"Flash fired, red-eye reduction mode, return light detected",73:"Flash fired, compulsory flash mode, red-eye reduction mode",77:"Flash fired, compulsory flash mode, red-eye reduction mode, return light not detected",79:"Flash fired, compulsory flash mode, red-eye reduction mode, return light detected",89:"Flash fired, auto mode, red-eye reduction mode",93:"Flash fired, auto mode, return light not detected, red-eye reduction mode",95:"Flash fired, auto mode, return light detected, red-eye reduction mode"},SensingMethod:{1:"Undefined",2:"One-chip color area sensor",3:"Two-chip color area sensor",4:"Three-chip color area sensor",5:"Color sequential area sensor",7:"Trilinear sensor",8:"Color sequential linear sensor"},SceneCaptureType:{0:"Standard",1:"Landscape",2:"Portrait",3:"Night scene"},SceneType:{1:"Directly photographed"},CustomRendered:{0:"Normal process",1:"Custom process"},WhiteBalance:{0:"Auto white balance",1:"Manual white balance"},GainControl:{0:"None",1:"Low gain up",2:"High gain up",3:"Low gain down",4:"High gain down"},Contrast:{0:"Normal",1:"Soft",2:"Hard"},Saturation:{0:"Normal",1:"Low saturation",2:"High saturation"},Sharpness:{0:"Normal",1:"Soft",2:"Hard"},SubjectDistanceRange:{0:"Unknown",1:"Macro",2:"Close view",3:"Distant view"},FileSource:{3:"DSC"},ComponentsConfiguration:{0:"",1:"Y",2:"Cb",3:"Cr",4:"R",5:"G",6:"B"},Orientation:{1:"top-left",2:"top-right",3:"bottom-right",4:"bottom-left",5:"left-top",6:"right-top",7:"right-bottom",8:"left-bottom"}},a.ExifMap.prototype.getText=function(a){var b=this.get(a);switch(a){case"LightSource":case"Flash":case"MeteringMode":case"ExposureProgram":case"SensingMethod":case"SceneCaptureType":case"SceneType":case"CustomRendered":case"WhiteBalance":case"GainControl":case"Contrast":case"Saturation":case"Sharpness":case"SubjectDistanceRange":case"FileSource":case"Orientation":return this.stringValues[a][b];case"ExifVersion":case"FlashpixVersion":return String.fromCharCode(b[0],b[1],b[2],b[3]);case"ComponentsConfiguration":return this.stringValues[a][b[0]]+this.stringValues[a][b[1]]+this.stringValues[a][b[2]]+this.stringValues[a][b[3]];case"GPSVersionID":return b[0]+"."+b[1]+"."+b[2]+"."+b[3]}return String(b)},function(a){var b,c=a.tags,d=a.map;for(b in c)c.hasOwnProperty(b)&&(d[c[b]]=b)}(a.ExifMap.prototype),a.ExifMap.prototype.getAll=function(){var a,b,c={};for(a in this)this.hasOwnProperty(a)&&(b=this.tags[a],b&&(c[b]=this.getText(b)));return c}});
|
@@ -0,0 +1,87 @@
|
|
1
|
+
/*
|
2
|
+
* JavaScript Templates 2.4.1
|
3
|
+
* https://github.com/blueimp/JavaScript-Templates
|
4
|
+
*
|
5
|
+
* Copyright 2011, Sebastian Tschan
|
6
|
+
* https://blueimp.net
|
7
|
+
*
|
8
|
+
* Licensed under the MIT license:
|
9
|
+
* http://www.opensource.org/licenses/MIT
|
10
|
+
*
|
11
|
+
* Inspired by John Resig's JavaScript Micro-Templating:
|
12
|
+
* http://ejohn.org/blog/javascript-micro-templating/
|
13
|
+
*/
|
14
|
+
|
15
|
+
/*jslint evil: true, regexp: true, unparam: true */
|
16
|
+
/*global document, define */
|
17
|
+
|
18
|
+
(function ($) {
|
19
|
+
"use strict";
|
20
|
+
var tmpl = function (str, data) {
|
21
|
+
var f = !/[^\w\-\.:]/.test(str) ? tmpl.cache[str] = tmpl.cache[str] ||
|
22
|
+
tmpl(tmpl.load(str)) :
|
23
|
+
new Function(
|
24
|
+
tmpl.arg + ',tmpl',
|
25
|
+
"var _e=tmpl.encode" + tmpl.helper + ",_s='" +
|
26
|
+
str.replace(tmpl.regexp, tmpl.func) +
|
27
|
+
"';return _s;"
|
28
|
+
);
|
29
|
+
return data ? f(data, tmpl) : function (data) {
|
30
|
+
return f(data, tmpl);
|
31
|
+
};
|
32
|
+
};
|
33
|
+
tmpl.cache = {};
|
34
|
+
tmpl.load = function (id) {
|
35
|
+
return document.getElementById(id).innerHTML;
|
36
|
+
};
|
37
|
+
tmpl.regexp = /([\s'\\])(?!(?:[^{]|\{(?!%))*%\})|(?:\{%(=|#)([\s\S]+?)%\})|(\{%)|(%\})/g;
|
38
|
+
tmpl.func = function (s, p1, p2, p3, p4, p5) {
|
39
|
+
if (p1) { // whitespace, quote and backspace in HTML context
|
40
|
+
return {
|
41
|
+
"\n": "\\n",
|
42
|
+
"\r": "\\r",
|
43
|
+
"\t": "\\t",
|
44
|
+
" " : " "
|
45
|
+
}[p1] || "\\" + p1;
|
46
|
+
}
|
47
|
+
if (p2) { // interpolation: {%=prop%}, or unescaped: {%#prop%}
|
48
|
+
if (p2 === "=") {
|
49
|
+
return "'+_e(" + p3 + ")+'";
|
50
|
+
}
|
51
|
+
return "'+(" + p3 + "==null?'':" + p3 + ")+'";
|
52
|
+
}
|
53
|
+
if (p4) { // evaluation start tag: {%
|
54
|
+
return "';";
|
55
|
+
}
|
56
|
+
if (p5) { // evaluation end tag: %}
|
57
|
+
return "_s+='";
|
58
|
+
}
|
59
|
+
};
|
60
|
+
tmpl.encReg = /[<>&"'\x00]/g;
|
61
|
+
tmpl.encMap = {
|
62
|
+
"<" : "<",
|
63
|
+
">" : ">",
|
64
|
+
"&" : "&",
|
65
|
+
"\"" : """,
|
66
|
+
"'" : "'"
|
67
|
+
};
|
68
|
+
tmpl.encode = function (s) {
|
69
|
+
/*jshint eqnull:true */
|
70
|
+
return (s == null ? "" : "" + s).replace(
|
71
|
+
tmpl.encReg,
|
72
|
+
function (c) {
|
73
|
+
return tmpl.encMap[c] || "";
|
74
|
+
}
|
75
|
+
);
|
76
|
+
};
|
77
|
+
tmpl.arg = "o";
|
78
|
+
tmpl.helper = ",print=function(s,e){_s+=e?(s==null?'':s):_e(s);}" +
|
79
|
+
",include=function(s,d){_s+=tmpl(s,d);}";
|
80
|
+
if (typeof define === "function" && define.amd) {
|
81
|
+
define(function () {
|
82
|
+
return tmpl;
|
83
|
+
});
|
84
|
+
} else {
|
85
|
+
$.tmpl = tmpl;
|
86
|
+
}
|
87
|
+
}(this));
|
@@ -0,0 +1,57 @@
|
|
1
|
+
@charset "UTF-8";
|
2
|
+
/*
|
3
|
+
* jQuery File Upload UI Plugin CSS
|
4
|
+
* https://github.com/blueimp/jQuery-File-Upload
|
5
|
+
*
|
6
|
+
* Copyright 2010, Sebastian Tschan
|
7
|
+
* https://blueimp.net
|
8
|
+
*
|
9
|
+
* Licensed under the MIT license:
|
10
|
+
* http://www.opensource.org/licenses/MIT
|
11
|
+
*/
|
12
|
+
|
13
|
+
.fileupload-buttonbar .btn,
|
14
|
+
.fileupload-buttonbar .toggle {
|
15
|
+
margin-bottom: 5px;
|
16
|
+
}
|
17
|
+
.progress-animated .progress-bar,
|
18
|
+
.progress-animated .bar {
|
19
|
+
background: image-url("rails_admin_uploader/progressbar.gif") !important;
|
20
|
+
filter: none;
|
21
|
+
}
|
22
|
+
.fileupload-process {
|
23
|
+
float: right;
|
24
|
+
display: none;
|
25
|
+
}
|
26
|
+
.fileupload-processing .fileupload-process,
|
27
|
+
.files .processing .preview {
|
28
|
+
display: block;
|
29
|
+
width: 32px;
|
30
|
+
height: 32px;
|
31
|
+
background: image-url("rails_admin_uploader/loading.gif") center no-repeat;
|
32
|
+
background-size: contain;
|
33
|
+
}
|
34
|
+
.files audio,
|
35
|
+
.files video {
|
36
|
+
max-width: 300px;
|
37
|
+
}
|
38
|
+
|
39
|
+
@media (max-width: 767px) {
|
40
|
+
.fileupload-buttonbar .toggle,
|
41
|
+
.files .toggle,
|
42
|
+
.files .btn span {
|
43
|
+
display: none;
|
44
|
+
}
|
45
|
+
.files .name {
|
46
|
+
width: 80px;
|
47
|
+
word-wrap: break-word;
|
48
|
+
}
|
49
|
+
.files audio,
|
50
|
+
.files video {
|
51
|
+
max-width: 80px;
|
52
|
+
}
|
53
|
+
.files img,
|
54
|
+
.files canvas {
|
55
|
+
max-width: 100%;
|
56
|
+
}
|
57
|
+
}
|
@@ -0,0 +1,37 @@
|
|
1
|
+
@charset "UTF-8";
|
2
|
+
/*
|
3
|
+
* jQuery File Upload Plugin CSS
|
4
|
+
* https://github.com/blueimp/jQuery-File-Upload
|
5
|
+
*
|
6
|
+
* Copyright 2013, Sebastian Tschan
|
7
|
+
* https://blueimp.net
|
8
|
+
*
|
9
|
+
* Licensed under the MIT license:
|
10
|
+
* http://www.opensource.org/licenses/MIT
|
11
|
+
*/
|
12
|
+
|
13
|
+
.fileinput-button {
|
14
|
+
position: relative;
|
15
|
+
overflow: hidden;
|
16
|
+
display: inline-block;
|
17
|
+
}
|
18
|
+
.fileinput-button input {
|
19
|
+
position: absolute;
|
20
|
+
top: 0;
|
21
|
+
right: 0;
|
22
|
+
margin: 0;
|
23
|
+
opacity: 0;
|
24
|
+
-ms-filter: 'alpha(opacity=0)';
|
25
|
+
font-size: 200px;
|
26
|
+
direction: ltr;
|
27
|
+
cursor: pointer;
|
28
|
+
}
|
29
|
+
|
30
|
+
/* Fixes for IE < 8 */
|
31
|
+
@media screen\9 {
|
32
|
+
.fileinput-button input {
|
33
|
+
filter: alpha(opacity=0);
|
34
|
+
font-size: 100%;
|
35
|
+
height: 100%;
|
36
|
+
}
|
37
|
+
}
|
@@ -0,0 +1,94 @@
|
|
1
|
+
module RailsAdminUploader
|
2
|
+
class AttachmentsController < ActionController::Base
|
3
|
+
before_action :find_obj
|
4
|
+
|
5
|
+
def index
|
6
|
+
authorize! :read, @obj
|
7
|
+
if @obj.nil?
|
8
|
+
render json: []
|
9
|
+
else
|
10
|
+
@imgs = @obj.send(params[:field]).accessible_by(current_ability)
|
11
|
+
if @flags[:sortable]
|
12
|
+
@imgs = @imgs.order(sort: :asc)
|
13
|
+
end
|
14
|
+
@imgs = @imgs.map(&:as_ra_json)
|
15
|
+
render json: {files: @imgs}
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def create
|
20
|
+
authorize! :read, @obj unless @obj.nil?
|
21
|
+
authorize! :create, @asset_klass
|
22
|
+
|
23
|
+
if params[:order]
|
24
|
+
sort()
|
25
|
+
return
|
26
|
+
end
|
27
|
+
|
28
|
+
ret = []
|
29
|
+
params[:files].each do |f|
|
30
|
+
img = @asset_klass.new(image: f)
|
31
|
+
if @obj.nil?
|
32
|
+
img.ra_token = params[:guid]
|
33
|
+
else
|
34
|
+
img.send("#{@asset_fk}=", @obj.id)
|
35
|
+
end
|
36
|
+
saved = img.save
|
37
|
+
data = img.as_ra_json
|
38
|
+
unless saved
|
39
|
+
data['error'] = img.errors.full_messages.join()
|
40
|
+
end
|
41
|
+
ret.push data
|
42
|
+
render json: {files: ret}
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def sort
|
47
|
+
order = params[:order]
|
48
|
+
@obj.send(params[:field]).accessible_by(current_ability).each do |i|
|
49
|
+
i.sort = order.index(i.id.to_s)
|
50
|
+
i.save!
|
51
|
+
end
|
52
|
+
render json: {success: true}
|
53
|
+
end
|
54
|
+
|
55
|
+
def update
|
56
|
+
authorize! :read, @obj unless @obj.nil?
|
57
|
+
@img = @obj.send(params[:field]).find(params[:id])
|
58
|
+
authorize! :update, @img
|
59
|
+
if @img.update_attributes(params.require(:img).permit(:enabled, :name))
|
60
|
+
render json: @img.as_ra_json
|
61
|
+
else
|
62
|
+
render json: {errors: @img.errors.full_messages.join("\n")}, status: 422
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
def destroy
|
67
|
+
authorize! :read, @obj unless @obj.nil?
|
68
|
+
@img = @obj.send(params[:field]).find(params[:id])
|
69
|
+
authorize! :destroy, @img
|
70
|
+
if @img.destroy
|
71
|
+
render json: {success: true}
|
72
|
+
else
|
73
|
+
render json: {errors: @img.errors.full_messages.join("\n")}, status: 422
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
private
|
78
|
+
def find_obj
|
79
|
+
@klass = params[:klass].safe_constantize
|
80
|
+
if @klass.respond_to?(:ra_columns) && @klass.ra_columns.map(&:to_s).include?(params[:field])
|
81
|
+
@ref = @klass.ra_get_reflection(params[:field])
|
82
|
+
@asset_klass = @ref.klass
|
83
|
+
@asset_fk = @ref.foreign_key
|
84
|
+
@flags = @klass.ra_flags(params[:field])
|
85
|
+
if params[:obj_id]
|
86
|
+
@obj = @klass.find(params[:obj_id])
|
87
|
+
end
|
88
|
+
else
|
89
|
+
render json: {error: 'bad OBJ'}, status: 422
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|