s3_cors_fileupload 0.2.1 → 0.3.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 +4 -4
- data/.travis.yml +4 -0
- data/CHANGELOG.md +10 -3
- data/Gemfile +11 -9
- data/Gemfile.lock +86 -65
- data/README.md +8 -4
- data/lib/generators/s3_cors_fileupload/install/install_generator.rb +5 -2
- data/lib/generators/s3_cors_fileupload/install/templates/s3_uploads_controller.rb +3 -1
- data/lib/generators/s3_cors_fileupload/install/templates/source_file.rb +4 -3
- data/lib/generators/s3_cors_fileupload/install/templates/views/erb/_template_download.html.erb +18 -7
- data/lib/generators/s3_cors_fileupload/install/templates/views/erb/_template_upload.html.erb +4 -4
- data/lib/generators/s3_cors_fileupload/install/templates/views/erb/_template_uploaded.html.erb +17 -6
- data/lib/generators/s3_cors_fileupload/install/templates/views/erb/index.html.erb +1 -1
- data/lib/generators/s3_cors_fileupload/install/templates/views/haml/_template_download.html.haml +14 -4
- data/lib/generators/s3_cors_fileupload/install/templates/views/haml/_template_upload.html.haml +5 -5
- data/lib/generators/s3_cors_fileupload/install/templates/views/haml/_template_uploaded.html.haml +12 -1
- data/lib/generators/s3_cors_fileupload/install/templates/views/haml/index.html.haml +1 -1
- data/lib/s3_cors_fileupload.rb +6 -0
- data/lib/s3_cors_fileupload/rails.rb +1 -1
- data/lib/s3_cors_fileupload/rails/form_helper.rb +15 -12
- data/lib/s3_cors_fileupload/version.rb +3 -3
- data/s3_cors_fileupload.gemspec +3 -4
- data/spec/dummy/Rakefile +0 -1
- data/spec/dummy/app/assets/javascripts/application.js +4 -3
- data/spec/dummy/app/assets/javascripts/s3_uploads.js +92 -0
- data/spec/dummy/app/assets/stylesheets/application.css +1 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -1
- data/spec/dummy/app/controllers/s3_uploads_controller.rb +56 -0
- data/spec/dummy/app/models/source_file.rb +54 -0
- data/spec/dummy/app/views/layouts/application.html.erb +2 -2
- data/spec/dummy/app/views/s3_uploads/_template_download.html.erb +43 -0
- data/spec/dummy/app/views/s3_uploads/_template_upload.html.erb +36 -0
- data/spec/dummy/app/views/s3_uploads/_template_uploaded.html.erb +41 -0
- data/spec/dummy/app/views/s3_uploads/index.html.erb +41 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/config.ru +1 -1
- data/spec/dummy/config/application.rb +2 -33
- data/spec/dummy/config/boot.rb +4 -9
- data/spec/dummy/config/environment.rb +2 -2
- data/spec/dummy/config/environments/development.rb +14 -19
- data/spec/dummy/config/environments/production.rb +40 -27
- data/spec/dummy/config/environments/test.rb +14 -12
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +6 -5
- data/spec/dummy/config/initializers/secret_token.rb +7 -2
- data/spec/dummy/config/initializers/session_store.rb +0 -5
- data/spec/dummy/config/initializers/wrap_parameters.rb +6 -6
- data/spec/dummy/config/locales/en.yml +20 -2
- data/spec/dummy/config/routes.rb +27 -24
- data/spec/dummy/db/migrate/20131001201535_create_source_files.rb +14 -0
- data/spec/dummy/db/schema.rb +27 -0
- data/spec/dummy/public/404.html +43 -11
- data/spec/dummy/public/422.html +43 -11
- data/spec/dummy/public/500.html +43 -11
- data/spec/features/uploads_spec.rb +37 -0
- data/spec/lib/s3_cors_fileupload/rails/engine_spec.rb +8 -0
- data/spec/lib/s3_cors_fileupload/rails/form_helper_spec.rb +30 -0
- data/spec/lib/s3_cors_fileupload/rails/policy_helper_spec.rb +95 -0
- data/spec/s3_cors_fileupload_spec.rb +8 -4
- data/spec/spec_helper.rb +8 -8
- data/spec/support/dummy.pdf +0 -0
- data/vendor/assets/javascripts/s3_cors_fileupload/index.js +1 -0
- data/vendor/assets/javascripts/s3_cors_fileupload/jquery.fileupload-image.js +111 -32
- data/vendor/assets/javascripts/s3_cors_fileupload/jquery.fileupload-ui.js +24 -18
- data/vendor/assets/javascripts/s3_cors_fileupload/jquery.fileupload-validate.js +7 -6
- data/vendor/assets/javascripts/s3_cors_fileupload/jquery.fileupload.js +22 -15
- data/vendor/assets/javascripts/s3_cors_fileupload/vendor/load-image-meta.js +137 -0
- data/vendor/assets/javascripts/s3_cors_fileupload/vendor/tmpl.js +8 -8
- data/vendor/assets/stylesheets/jquery.fileupload-ui.css.erb +2 -1
- metadata +56 -28
- data/spec/dummy/script/rails +0 -6
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
feature 'Uploads' do
|
|
4
|
+
background { visit source_files_path }
|
|
5
|
+
|
|
6
|
+
describe 'GET #index' do
|
|
7
|
+
scenario { page.should have_selector('h2', :text => 'Upload file(s)') }
|
|
8
|
+
|
|
9
|
+
scenario :s3_cors_fileupload_form_tag do
|
|
10
|
+
within('form#fileupload') do
|
|
11
|
+
page.should have_selector('div.fileupload-buttonbar')
|
|
12
|
+
page.should have_selector('table#upload_files')
|
|
13
|
+
page.should have_selector('input[type=file]#file')
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
scenario "Attaching files", :js => true do
|
|
18
|
+
within('form#fileupload') do
|
|
19
|
+
within('table#upload_files tbody.files') do
|
|
20
|
+
page.should_not have_selector('tr')
|
|
21
|
+
page.text.should be_blank
|
|
22
|
+
end
|
|
23
|
+
attach_file('file', File.expand_path('../../support/dummy.pdf', __FILE__))
|
|
24
|
+
# After a file is attached, it should get added to the table#upload_files to be uploaded
|
|
25
|
+
within('table#upload_files tbody.files') do
|
|
26
|
+
page.should have_selector('tr.template-upload')
|
|
27
|
+
within('tr.template-upload') do
|
|
28
|
+
page.should have_selector('td', :text => 'dummy.pdf')
|
|
29
|
+
page.should have_selector('td', :text => '7.84 KB')
|
|
30
|
+
page.should have_selector('td', :text => 'Start')
|
|
31
|
+
page.should have_selector('td', :text => 'Cancel')
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe S3CorsFileupload::FormHelper do
|
|
4
|
+
it { S3CorsFileupload::FormHelper.should be_instance_of(Module) }
|
|
5
|
+
it { ActionView::Base.should include(S3CorsFileupload::FormHelper) }
|
|
6
|
+
|
|
7
|
+
describe "Instance Methods" do
|
|
8
|
+
subject { ActionView::Base.new }
|
|
9
|
+
|
|
10
|
+
describe :s3_cors_fileupload_form_tag do
|
|
11
|
+
it { should respond_to(:s3_cors_fileupload_form_tag) }
|
|
12
|
+
|
|
13
|
+
it "should return HTML for the jQuery-File-Upload form" do
|
|
14
|
+
value = subject.s3_cors_fileupload_form_tag
|
|
15
|
+
value.should be_a(String)
|
|
16
|
+
value.should be_instance_of(ActiveSupport::SafeBuffer)
|
|
17
|
+
value.should be_html_safe
|
|
18
|
+
value.match(/<form/).should_not be_nil
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
describe :s3_cors_fileupload_form do
|
|
23
|
+
it { should respond_to(:s3_cors_fileupload_form) }
|
|
24
|
+
|
|
25
|
+
it "should be an alias for the `s3_cors_fileupload_form_tag` method" do
|
|
26
|
+
subject.method(:s3_cors_fileupload_form).should == subject.method(:s3_cors_fileupload_form_tag)
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
|
|
3
|
+
describe S3CorsFileupload::PolicyHelper do
|
|
4
|
+
it { S3CorsFileupload::PolicyHelper.should be_instance_of(Class) }
|
|
5
|
+
|
|
6
|
+
let(:options) { {} }
|
|
7
|
+
let(:policy_helper) { S3CorsFileupload::PolicyHelper.new(options) }
|
|
8
|
+
|
|
9
|
+
describe "Constructor" do
|
|
10
|
+
context "no arguments" do
|
|
11
|
+
it "should build without error" do
|
|
12
|
+
policy_helper
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "should use default values" do
|
|
16
|
+
policy_helper.options[:acl].should == 'public-read'
|
|
17
|
+
policy_helper.options[:max_file_size].should == S3CorsFileupload::Config.max_file_size || 524288000
|
|
18
|
+
policy_helper.options[:bucket].should == S3CorsFileupload::Config.bucket
|
|
19
|
+
policy_helper.options[:secret_access_key].should == S3CorsFileupload::Config.secret_access_key
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
context "arguments" do
|
|
24
|
+
context :acl do
|
|
25
|
+
let(:options) { {:acl => 'private'} }
|
|
26
|
+
it { policy_helper.options[:acl].should == 'private' }
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
context :max_file_size do
|
|
30
|
+
let(:options) { {:max_file_size => 10} }
|
|
31
|
+
it { policy_helper.options[:max_file_size].should == 10 }
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
context :bucket do
|
|
35
|
+
let(:options) { {:bucket => 'foobar'} }
|
|
36
|
+
it { policy_helper.options[:bucket].should == 'foobar' }
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
context :bucket do
|
|
40
|
+
let(:options) { {:bucket => 'foobar'} }
|
|
41
|
+
it { policy_helper.options[:bucket].should == 'foobar' }
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
describe "Instance Methods" do
|
|
47
|
+
describe :policy_document do
|
|
48
|
+
it { should respond_to(:policy_document) }
|
|
49
|
+
|
|
50
|
+
it "should generate a policy document for AWS S3 and use `Base64` to encode it" do
|
|
51
|
+
value = policy_helper.policy_document
|
|
52
|
+
value.should be_instance_of(String)
|
|
53
|
+
# decode and then deserialize the value returned from the policy document
|
|
54
|
+
value = MultiJson.load Base64.decode64(value), symbolize_keys: true
|
|
55
|
+
value.should be_instance_of(Hash)
|
|
56
|
+
value.should have_key(:expiration)
|
|
57
|
+
value.should have_key(:conditions)
|
|
58
|
+
value[:conditions].should == [
|
|
59
|
+
{ bucket: policy_helper.options[:bucket] },
|
|
60
|
+
{ acl: policy_helper.options[:acl] },
|
|
61
|
+
{ success_action_status: '201' },
|
|
62
|
+
["content-length-range", 0, policy_helper.options[:max_file_size]],
|
|
63
|
+
["starts-with", "$utf8", ""],
|
|
64
|
+
["starts-with", "$key", ""],
|
|
65
|
+
["starts-with", "$Content-Type", ""]
|
|
66
|
+
]
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
it "should cache the return value in an instance variable" do
|
|
70
|
+
policy_helper.instance_variable_get(:@policy_document).should be_nil
|
|
71
|
+
value = policy_helper.policy_document
|
|
72
|
+
policy_helper.instance_variable_get(:@policy_document).should_not be_nil
|
|
73
|
+
policy_helper.instance_variable_get(:@policy_document).should == value
|
|
74
|
+
end
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
describe :upload_signature do
|
|
78
|
+
it { should respond_to(:upload_signature) }
|
|
79
|
+
|
|
80
|
+
it "should create an upload signature based off our secret_access_key, and convert it to a string" do
|
|
81
|
+
policy_helper.upload_signature.should == Base64.encode64(
|
|
82
|
+
OpenSSL::HMAC.digest(OpenSSL::Digest::SHA1.new, policy_helper.options[:secret_access_key], policy_helper.policy_document)
|
|
83
|
+
).gsub(/\n/, '')
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
it "should cache the return value in an instance variable" do
|
|
87
|
+
policy_helper.instance_variable_get(:@upload_signature).should be_nil
|
|
88
|
+
value = policy_helper.upload_signature
|
|
89
|
+
policy_helper.instance_variable_get(:@upload_signature).should_not be_nil
|
|
90
|
+
policy_helper.instance_variable_get(:@upload_signature).should == value
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
end
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe S3CorsFileupload do
|
|
4
|
-
|
|
5
4
|
it { should be_instance_of(Module) }
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
|
|
6
|
+
describe "Methods" do
|
|
7
|
+
describe :active_record_protected_attributes? do
|
|
8
|
+
it { should respond_to(:active_record_protected_attributes?) }
|
|
9
|
+
|
|
10
|
+
its(:active_record_protected_attributes?) { should be_false } # Since the dummy app isn't using `ProtectedAttributes`
|
|
11
|
+
end
|
|
12
|
+
end
|
|
9
13
|
end
|
data/spec/spec_helper.rb
CHANGED
|
@@ -3,6 +3,14 @@ require File.expand_path('../dummy/config/environment', __FILE__)
|
|
|
3
3
|
# the gem's library gets included through a require statement on 'dummy/config/application.rb'
|
|
4
4
|
require 'rspec/rails'
|
|
5
5
|
require 'rspec/autorun'
|
|
6
|
+
require 'capybara/rspec'
|
|
7
|
+
require 'capybara/rails'
|
|
8
|
+
require 'capybara/poltergeist'
|
|
9
|
+
|
|
10
|
+
Capybara.javascript_driver = :poltergeist
|
|
11
|
+
|
|
12
|
+
# Run any available migration in the dummy app
|
|
13
|
+
ActiveRecord::Migrator.migrate("#{::Rails.root}/db/migrate")
|
|
6
14
|
|
|
7
15
|
# Requires supporting ruby files with custom matchers and macros, etc,
|
|
8
16
|
# in spec/support/ and its subdirectories.
|
|
@@ -38,12 +46,4 @@ RSpec.configure do |config|
|
|
|
38
46
|
# the seed, which is printed after each run.
|
|
39
47
|
# --seed 1234
|
|
40
48
|
config.order = 'random'
|
|
41
|
-
|
|
42
|
-
# Prep for running the test suite
|
|
43
|
-
config.before(:all) do
|
|
44
|
-
# Invoke the generator for the gem.
|
|
45
|
-
# ::Rails::Generators.invoke('s3_cors_fileupload:install')
|
|
46
|
-
# Run any migrations for the dummy app prior to running the spec suite.
|
|
47
|
-
# ActiveRecord::Migrator.migrate "#{::Rails.root}/db/migrate"
|
|
48
|
-
end
|
|
49
49
|
end
|
|
Binary file
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
//= require s3_cors_fileupload/vendor/jquery.ui.widget
|
|
2
2
|
//= require s3_cors_fileupload/vendor/tmpl
|
|
3
3
|
//= require s3_cors_fileupload/vendor/load-image
|
|
4
|
+
//= require s3_cors_fileupload/vendor/load-image-meta
|
|
4
5
|
//= require s3_cors_fileupload/jquery.iframe-transport
|
|
5
6
|
//= require s3_cors_fileupload/jquery.fileupload
|
|
6
7
|
//= require s3_cors_fileupload/jquery.fileupload-process
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* jQuery File Upload Image Preview & Resize Plugin 1.
|
|
2
|
+
* jQuery File Upload Image Preview & Resize Plugin 1.2.3
|
|
3
3
|
* https://github.com/blueimp/jQuery-File-Upload
|
|
4
4
|
*
|
|
5
5
|
* Copyright 2013, Sebastian Tschan
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
/*jslint nomen: true, unparam: true, regexp: true */
|
|
13
|
-
/*global define, window */
|
|
13
|
+
/*global define, window, document, DataView, Blob, Uint8Array */
|
|
14
14
|
|
|
15
15
|
(function (factory) {
|
|
16
16
|
'use strict';
|
|
@@ -19,6 +19,9 @@
|
|
|
19
19
|
define([
|
|
20
20
|
'jquery',
|
|
21
21
|
'load-image',
|
|
22
|
+
'load-image-meta',
|
|
23
|
+
'load-image-exif',
|
|
24
|
+
'load-image-ios',
|
|
22
25
|
'canvas-to-blob',
|
|
23
26
|
'./jquery.fileupload-process'
|
|
24
27
|
], factory);
|
|
@@ -34,37 +37,55 @@
|
|
|
34
37
|
|
|
35
38
|
// Prepend to the default processQueue:
|
|
36
39
|
$.blueimp.fileupload.prototype.options.processQueue.unshift(
|
|
40
|
+
{
|
|
41
|
+
action: 'loadImageMetaData',
|
|
42
|
+
disableImageHead: '@',
|
|
43
|
+
disableExif: '@',
|
|
44
|
+
disableExifThumbnail: '@',
|
|
45
|
+
disableExifSub: '@',
|
|
46
|
+
disableExifGps: '@',
|
|
47
|
+
disabled: '@disableImageMetaDataLoad'
|
|
48
|
+
},
|
|
37
49
|
{
|
|
38
50
|
action: 'loadImage',
|
|
39
|
-
//
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
noRevoke: '@loadImageNoRevoke',
|
|
51
|
+
// Use the action as prefix for the "@" options:
|
|
52
|
+
prefix: true,
|
|
53
|
+
fileTypes: '@',
|
|
54
|
+
maxFileSize: '@',
|
|
55
|
+
noRevoke: '@',
|
|
45
56
|
disabled: '@disableImageLoad'
|
|
46
57
|
},
|
|
47
58
|
{
|
|
48
59
|
action: 'resizeImage',
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
60
|
+
// Use "image" as prefix for the "@" options:
|
|
61
|
+
prefix: 'image',
|
|
62
|
+
maxWidth: '@',
|
|
63
|
+
maxHeight: '@',
|
|
64
|
+
minWidth: '@',
|
|
65
|
+
minHeight: '@',
|
|
66
|
+
crop: '@',
|
|
54
67
|
disabled: '@disableImageResize'
|
|
55
68
|
},
|
|
56
69
|
{
|
|
57
70
|
action: 'saveImage',
|
|
58
71
|
disabled: '@disableImageResize'
|
|
59
72
|
},
|
|
73
|
+
{
|
|
74
|
+
action: 'saveImageMetaData',
|
|
75
|
+
disabled: '@disableImageMetaDataSave'
|
|
76
|
+
},
|
|
60
77
|
{
|
|
61
78
|
action: 'resizeImage',
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
79
|
+
// Use "preview" as prefix for the "@" options:
|
|
80
|
+
prefix: 'preview',
|
|
81
|
+
maxWidth: '@',
|
|
82
|
+
maxHeight: '@',
|
|
83
|
+
minWidth: '@',
|
|
84
|
+
minHeight: '@',
|
|
85
|
+
crop: '@',
|
|
86
|
+
orientation: '@',
|
|
87
|
+
thumbnail: '@',
|
|
88
|
+
canvas: '@',
|
|
68
89
|
disabled: '@disableImagePreview'
|
|
69
90
|
},
|
|
70
91
|
{
|
|
@@ -83,7 +104,7 @@
|
|
|
83
104
|
// matched against the file type:
|
|
84
105
|
loadImageFileTypes: /^image\/(gif|jpeg|png)$/,
|
|
85
106
|
// The maximum file size of images to load:
|
|
86
|
-
loadImageMaxFileSize:
|
|
107
|
+
loadImageMaxFileSize: 10000000, // 10MB
|
|
87
108
|
// The maximum width of resized images:
|
|
88
109
|
imageMaxWidth: 1920,
|
|
89
110
|
// The maximum height of resized images:
|
|
@@ -96,10 +117,15 @@
|
|
|
96
117
|
previewMaxWidth: 80,
|
|
97
118
|
// The maximum height of the preview images:
|
|
98
119
|
previewMaxHeight: 80,
|
|
120
|
+
// Defines the preview orientation (1-8) or takes the orientation
|
|
121
|
+
// value from Exif data if set to true:
|
|
122
|
+
previewOrientation: true,
|
|
123
|
+
// Create the preview using the Exif data thumbnail:
|
|
124
|
+
previewThumbnail: true,
|
|
99
125
|
// Define if preview images should be cropped or only scaled:
|
|
100
126
|
previewCrop: false,
|
|
101
127
|
// Define if preview images should be resized as canvas elements:
|
|
102
|
-
|
|
128
|
+
previewCanvas: true
|
|
103
129
|
},
|
|
104
130
|
|
|
105
131
|
processActions: {
|
|
@@ -122,15 +148,14 @@
|
|
|
122
148
|
!loadImage(
|
|
123
149
|
file,
|
|
124
150
|
function (img) {
|
|
125
|
-
if (
|
|
126
|
-
|
|
151
|
+
if (img.src) {
|
|
152
|
+
data.img = img;
|
|
127
153
|
}
|
|
128
|
-
data.img = img;
|
|
129
154
|
dfd.resolveWith(that, [data]);
|
|
130
155
|
},
|
|
131
156
|
options
|
|
132
157
|
)) {
|
|
133
|
-
|
|
158
|
+
return data;
|
|
134
159
|
}
|
|
135
160
|
return dfd.promise();
|
|
136
161
|
},
|
|
@@ -140,14 +165,38 @@
|
|
|
140
165
|
// Accepts the options maxWidth, maxHeight, minWidth,
|
|
141
166
|
// minHeight, canvas and crop:
|
|
142
167
|
resizeImage: function (data, options) {
|
|
168
|
+
if (options.disabled) {
|
|
169
|
+
return data;
|
|
170
|
+
}
|
|
171
|
+
var that = this,
|
|
172
|
+
dfd = $.Deferred(),
|
|
173
|
+
resolve = function (newImg) {
|
|
174
|
+
data[newImg.getContext ? 'canvas' : 'img'] = newImg;
|
|
175
|
+
dfd.resolveWith(that, [data]);
|
|
176
|
+
},
|
|
177
|
+
thumbnail,
|
|
178
|
+
img,
|
|
179
|
+
newImg;
|
|
143
180
|
options = $.extend({canvas: true}, options);
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
if (
|
|
149
|
-
|
|
150
|
-
|
|
181
|
+
if (data.exif) {
|
|
182
|
+
if (options.orientation === true) {
|
|
183
|
+
options.orientation = data.exif.get('Orientation');
|
|
184
|
+
}
|
|
185
|
+
if (options.thumbnail) {
|
|
186
|
+
thumbnail = data.exif.get('Thumbnail');
|
|
187
|
+
if (thumbnail) {
|
|
188
|
+
loadImage(thumbnail, resolve, options);
|
|
189
|
+
return dfd.promise();
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
img = (options.canvas && data.canvas) || data.img;
|
|
194
|
+
if (img) {
|
|
195
|
+
newImg = loadImage.scale(img, options);
|
|
196
|
+
if (newImg.width !== img.width ||
|
|
197
|
+
newImg.height !== img.height) {
|
|
198
|
+
resolve(newImg);
|
|
199
|
+
return dfd.promise();
|
|
151
200
|
}
|
|
152
201
|
}
|
|
153
202
|
return data;
|
|
@@ -196,6 +245,36 @@
|
|
|
196
245
|
return dfd.promise();
|
|
197
246
|
},
|
|
198
247
|
|
|
248
|
+
loadImageMetaData: function (data, options) {
|
|
249
|
+
if (options.disabled) {
|
|
250
|
+
return data;
|
|
251
|
+
}
|
|
252
|
+
var that = this,
|
|
253
|
+
dfd = $.Deferred();
|
|
254
|
+
loadImage.parseMetaData(data.files[data.index], function (result) {
|
|
255
|
+
$.extend(data, result);
|
|
256
|
+
dfd.resolveWith(that, [data]);
|
|
257
|
+
}, options);
|
|
258
|
+
return dfd.promise();
|
|
259
|
+
},
|
|
260
|
+
|
|
261
|
+
saveImageMetaData: function (data, options) {
|
|
262
|
+
if (!(data.imageHead && data.canvas &&
|
|
263
|
+
data.canvas.toBlob && !options.disabled)) {
|
|
264
|
+
return data;
|
|
265
|
+
}
|
|
266
|
+
var file = data.files[data.index],
|
|
267
|
+
blob = new Blob([
|
|
268
|
+
data.imageHead,
|
|
269
|
+
// Resized images always have a head size of 20 bytes,
|
|
270
|
+
// including the JPEG marker and a minimal JFIF header:
|
|
271
|
+
this._blobSlice.call(file, 20)
|
|
272
|
+
], {type: file.type});
|
|
273
|
+
blob.name = file.name;
|
|
274
|
+
data.files[data.index] = blob;
|
|
275
|
+
return data;
|
|
276
|
+
},
|
|
277
|
+
|
|
199
278
|
// Sets the resized version of the image as a property of the
|
|
200
279
|
// file object, must be called after "saveImage":
|
|
201
280
|
setImage: function (data, options) {
|