fileapi 0.1.0 → 0.1.2
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.
@@ -1,4 +1,4 @@
|
|
1
|
-
/*! FileAPI 2.0.
|
1
|
+
/*! FileAPI 2.0.11 - BSD | git://github.com/mailru/FileAPI.git
|
2
2
|
* FileAPI — a set of javascript tools for working with files. Multiupload, drag'n'drop and chunked file upload. Images: crop, resize and auto orientation by EXIF.
|
3
3
|
*/
|
4
4
|
|
@@ -105,6 +105,7 @@
|
|
105
105
|
document = window.document,
|
106
106
|
doctype = document.doctype || {},
|
107
107
|
userAgent = window.navigator.userAgent,
|
108
|
+
safari = /safari\//i.test(userAgent) && !/chrome\//i.test(userAgent),
|
108
109
|
|
109
110
|
// https://github.com/blueimp/JavaScript-Load-Image/blob/master/load-image.js#L48
|
110
111
|
apiURL = (window.createObjectURL && window) || (window.URL && URL.revokeObjectURL && URL) || (window.webkitURL && webkitURL),
|
@@ -119,12 +120,14 @@
|
|
119
120
|
jQuery = window.jQuery,
|
120
121
|
|
121
122
|
html5 = !!(File && (FileReader && (window.Uint8Array || FormData || XMLHttpRequest.prototype.sendAsBinary)))
|
122
|
-
&& !(
|
123
|
+
&& !(safari && /windows/i.test(userAgent)), // BugFix: https://github.com/mailru/FileAPI/issues/25
|
123
124
|
|
124
125
|
cors = html5 && ('withCredentials' in (new XMLHttpRequest)),
|
125
126
|
|
126
127
|
chunked = html5 && !!Blob && !!(Blob.prototype.webkitSlice || Blob.prototype.mozSlice || Blob.prototype.slice),
|
127
128
|
|
129
|
+
normalize = ('' + ''.normalize).indexOf('[native code]') > 0,
|
130
|
+
|
128
131
|
// https://github.com/blueimp/JavaScript-Canvas-to-Blob
|
129
132
|
dataURLtoBlob = window.dataURLtoBlob,
|
130
133
|
|
@@ -280,7 +283,7 @@
|
|
280
283
|
* FileAPI (core object)
|
281
284
|
*/
|
282
285
|
api = {
|
283
|
-
version: '2.0.
|
286
|
+
version: '2.0.11',
|
284
287
|
|
285
288
|
cors: false,
|
286
289
|
html5: true,
|
@@ -795,28 +798,84 @@
|
|
795
798
|
getDropFiles: function (evt, callback){
|
796
799
|
var
|
797
800
|
files = []
|
801
|
+
, all = []
|
802
|
+
, items
|
798
803
|
, dataTransfer = _getDataTransfer(evt)
|
799
|
-
,
|
800
|
-
,
|
804
|
+
, transFiles = dataTransfer.files
|
805
|
+
, transItems = dataTransfer.items
|
806
|
+
, entrySupport = _isArray(transItems) && transItems[0] && _getAsEntry(transItems[0])
|
807
|
+
, queue = api.queue(function (){ callback(files, all); })
|
801
808
|
;
|
802
809
|
|
803
|
-
|
810
|
+
if( entrySupport ){
|
811
|
+
if( normalize && transFiles ){
|
812
|
+
var
|
813
|
+
i = transFiles.length
|
814
|
+
, file
|
815
|
+
, entry
|
816
|
+
;
|
817
|
+
|
818
|
+
items = new Array(i);
|
819
|
+
while( i-- ){
|
820
|
+
file = transFiles[i];
|
821
|
+
|
822
|
+
try {
|
823
|
+
entry = _getAsEntry(transItems[i]);
|
824
|
+
}
|
825
|
+
catch( err ){
|
826
|
+
api.log('[err] getDropFiles: ', err);
|
827
|
+
entry = null;
|
828
|
+
}
|
829
|
+
|
830
|
+
if( _isEntry(entry) ){
|
831
|
+
// OSX filesystems use Unicode Normalization Form D (NFD),
|
832
|
+
// and entry.file(…) can't read the files with the same names
|
833
|
+
if( entry.isDirectory || (entry.isFile && file.name == file.name.normalize('NFC')) ){
|
834
|
+
items[i] = entry;
|
835
|
+
}
|
836
|
+
else {
|
837
|
+
items[i] = file;
|
838
|
+
}
|
839
|
+
}
|
840
|
+
else {
|
841
|
+
items[i] = file;
|
842
|
+
}
|
843
|
+
}
|
844
|
+
}
|
845
|
+
else {
|
846
|
+
items = transItems;
|
847
|
+
}
|
848
|
+
}
|
849
|
+
else {
|
850
|
+
items = transFiles;
|
851
|
+
}
|
852
|
+
|
853
|
+
_each(items || [], function (item){
|
804
854
|
queue.inc();
|
805
855
|
|
806
856
|
try {
|
807
|
-
if( entrySupport ){
|
808
|
-
_readEntryAsFiles(item, function (err, entryFiles){
|
857
|
+
if( entrySupport && _isEntry(item) ){
|
858
|
+
_readEntryAsFiles(item, function (err, entryFiles, allEntries){
|
809
859
|
if( err ){
|
810
860
|
api.log('[err] getDropFiles:', err);
|
811
861
|
} else {
|
812
862
|
files.push.apply(files, entryFiles);
|
813
863
|
}
|
864
|
+
all.push.apply(all, allEntries);
|
865
|
+
|
814
866
|
queue.next();
|
815
867
|
});
|
816
868
|
}
|
817
869
|
else {
|
818
|
-
_isRegularFile(item, function (yes){
|
819
|
-
yes
|
870
|
+
_isRegularFile(item, function (yes, err){
|
871
|
+
if( yes ){
|
872
|
+
files.push(item);
|
873
|
+
}
|
874
|
+
else {
|
875
|
+
item.error = err;
|
876
|
+
}
|
877
|
+
all.push(item);
|
878
|
+
|
820
879
|
queue.next();
|
821
880
|
});
|
822
881
|
}
|
@@ -1491,13 +1550,13 @@
|
|
1491
1550
|
}
|
1492
1551
|
|
1493
1552
|
|
1494
|
-
function _hasSupportReadAs(
|
1495
|
-
return FileReader && !!FileReader.prototype['readAs'+
|
1553
|
+
function _hasSupportReadAs(method){
|
1554
|
+
return FileReader && !!FileReader.prototype['readAs' + method];
|
1496
1555
|
}
|
1497
1556
|
|
1498
1557
|
|
1499
|
-
function _readAs(file, fn,
|
1500
|
-
if( api.isBlob(file) && _hasSupportReadAs(
|
1558
|
+
function _readAs(file, fn, method, encoding){
|
1559
|
+
if( api.isBlob(file) && _hasSupportReadAs(method) ){
|
1501
1560
|
var Reader = new FileReader;
|
1502
1561
|
|
1503
1562
|
// Add event listener
|
@@ -1519,10 +1578,10 @@
|
|
1519
1578
|
try {
|
1520
1579
|
// ReadAs ...
|
1521
1580
|
if( encoding ){
|
1522
|
-
Reader['readAs'+
|
1581
|
+
Reader['readAs' + method](file, encoding);
|
1523
1582
|
}
|
1524
1583
|
else {
|
1525
|
-
Reader['readAs'+
|
1584
|
+
Reader['readAs' + method](file);
|
1526
1585
|
}
|
1527
1586
|
}
|
1528
1587
|
catch (err){
|
@@ -1530,33 +1589,36 @@
|
|
1530
1589
|
}
|
1531
1590
|
}
|
1532
1591
|
else {
|
1533
|
-
_emit(file, fn, 'error', undef, { error: 'filreader_not_support_'+
|
1592
|
+
_emit(file, fn, 'error', undef, { error: 'filreader_not_support_' + method });
|
1534
1593
|
}
|
1535
1594
|
}
|
1536
1595
|
|
1537
1596
|
|
1538
1597
|
function _isRegularFile(file, callback){
|
1539
1598
|
// http://stackoverflow.com/questions/8856628/detecting-folders-directories-in-javascript-filelist-objects
|
1540
|
-
if( !file.type && (file.size % 4096) === 0 && (file.size <= 102400) ){
|
1599
|
+
if( !file.type && (safari || ((file.size % 4096) === 0 && (file.size <= 102400))) ){
|
1541
1600
|
if( FileReader ){
|
1542
1601
|
try {
|
1543
|
-
var
|
1602
|
+
var reader = new FileReader();
|
1544
1603
|
|
1545
|
-
_one(
|
1604
|
+
_one(reader, _readerEvents, function (evt){
|
1546
1605
|
var isFile = evt.type != 'error';
|
1547
|
-
callback(isFile);
|
1548
1606
|
if( isFile ){
|
1549
|
-
|
1607
|
+
reader.abort();
|
1608
|
+
callback(isFile);
|
1609
|
+
}
|
1610
|
+
else {
|
1611
|
+
callback(false, reader.error);
|
1550
1612
|
}
|
1551
1613
|
});
|
1552
1614
|
|
1553
|
-
|
1615
|
+
reader.readAsDataURL(file);
|
1554
1616
|
} catch( err ){
|
1555
|
-
callback(false);
|
1617
|
+
callback(false, err);
|
1556
1618
|
}
|
1557
1619
|
}
|
1558
1620
|
else {
|
1559
|
-
callback(null);
|
1621
|
+
callback(null, new Error('FileReader is not supported'));
|
1560
1622
|
}
|
1561
1623
|
}
|
1562
1624
|
else {
|
@@ -1565,6 +1627,11 @@
|
|
1565
1627
|
}
|
1566
1628
|
|
1567
1629
|
|
1630
|
+
function _isEntry(item){
|
1631
|
+
return item && (item.isFile || item.isDirectory);
|
1632
|
+
}
|
1633
|
+
|
1634
|
+
|
1568
1635
|
function _getAsEntry(item){
|
1569
1636
|
var entry;
|
1570
1637
|
if( item.getAsEntry ){ entry = item.getAsEntry(); }
|
@@ -1576,45 +1643,68 @@
|
|
1576
1643
|
function _readEntryAsFiles(entry, callback){
|
1577
1644
|
if( !entry ){
|
1578
1645
|
// error
|
1579
|
-
|
1646
|
+
var err = new Error('invalid entry');
|
1647
|
+
entry = new Object(entry);
|
1648
|
+
entry.error = err;
|
1649
|
+
callback(err.message, [], [entry]);
|
1580
1650
|
}
|
1581
1651
|
else if( entry.isFile ){
|
1582
1652
|
// Read as file
|
1583
|
-
entry.file(function(file){
|
1653
|
+
entry.file(function (file){
|
1584
1654
|
// success
|
1585
1655
|
file.fullPath = entry.fullPath;
|
1586
|
-
callback(false, [file]);
|
1656
|
+
callback(false, [file], [file]);
|
1587
1657
|
}, function (err){
|
1588
1658
|
// error
|
1589
|
-
|
1659
|
+
entry.error = err;
|
1660
|
+
callback('FileError.code: ' + err.code, [], [entry]);
|
1590
1661
|
});
|
1591
1662
|
}
|
1592
1663
|
else if( entry.isDirectory ){
|
1593
|
-
var
|
1664
|
+
var
|
1665
|
+
reader = entry.createReader()
|
1666
|
+
, firstAttempt = true
|
1667
|
+
, files = []
|
1668
|
+
, all = [entry]
|
1669
|
+
;
|
1670
|
+
|
1671
|
+
var onerror = function (err){
|
1672
|
+
// error
|
1673
|
+
entry.error = err;
|
1674
|
+
callback('DirectoryError.code: ' + err.code, files, all);
|
1675
|
+
};
|
1676
|
+
var ondone = function ondone(entries){
|
1677
|
+
if( firstAttempt ){
|
1678
|
+
firstAttempt = false;
|
1679
|
+
if( !entries.length ){
|
1680
|
+
entry.error = new Error('directory is empty');
|
1681
|
+
}
|
1682
|
+
}
|
1594
1683
|
|
1595
|
-
reader.readEntries(function(entries){
|
1596
1684
|
// success
|
1597
|
-
|
1598
|
-
|
1599
|
-
|
1600
|
-
|
1601
|
-
|
1602
|
-
|
1603
|
-
|
1604
|
-
}
|
1685
|
+
if( entries.length ){
|
1686
|
+
api.afor(entries, function (next, entry){
|
1687
|
+
_readEntryAsFiles(entry, function (err, entryFiles, allEntries){
|
1688
|
+
if( !err ){
|
1689
|
+
files = files.concat(entryFiles);
|
1690
|
+
}
|
1691
|
+
all = all.concat(allEntries);
|
1605
1692
|
|
1606
|
-
|
1607
|
-
|
1608
|
-
|
1609
|
-
|
1610
|
-
|
1611
|
-
|
1693
|
+
if( next ){
|
1694
|
+
next();
|
1695
|
+
}
|
1696
|
+
else {
|
1697
|
+
reader.readEntries(ondone, onerror);
|
1698
|
+
}
|
1699
|
+
});
|
1612
1700
|
});
|
1613
|
-
}
|
1614
|
-
|
1615
|
-
|
1616
|
-
|
1617
|
-
}
|
1701
|
+
}
|
1702
|
+
else {
|
1703
|
+
callback(false, files, all);
|
1704
|
+
}
|
1705
|
+
};
|
1706
|
+
|
1707
|
+
reader.readEntries(ondone, onerror);
|
1618
1708
|
}
|
1619
1709
|
else {
|
1620
1710
|
_readEntryAsFiles(_getAsEntry(entry), callback);
|
@@ -1735,8 +1825,8 @@
|
|
1735
1825
|
_type = 0;
|
1736
1826
|
onHover.call(evt[currentTarget], false, evt);
|
1737
1827
|
|
1738
|
-
api.getDropFiles(evt, function (files){
|
1739
|
-
onDrop.call(evt[currentTarget], files, evt);
|
1828
|
+
api.getDropFiles(evt, function (files, all){
|
1829
|
+
onDrop.call(evt[currentTarget], files, all, evt);
|
1740
1830
|
});
|
1741
1831
|
});
|
1742
1832
|
}
|
@@ -2528,7 +2618,13 @@
|
|
2528
2618
|
});
|
2529
2619
|
|
2530
2620
|
this.each(function (file){
|
2531
|
-
|
2621
|
+
try{
|
2622
|
+
next(file, data, queue, arg);
|
2623
|
+
}
|
2624
|
+
catch( err ){
|
2625
|
+
api.log('FileAPI.Form._to: ' + err.message);
|
2626
|
+
complete(err);
|
2627
|
+
}
|
2532
2628
|
});
|
2533
2629
|
|
2534
2630
|
queue.check();
|
@@ -2756,14 +2852,19 @@
|
|
2756
2852
|
var _this = this, options = this.options;
|
2757
2853
|
|
2758
2854
|
FormData.toData(function (data){
|
2759
|
-
|
2760
|
-
|
2761
|
-
|
2855
|
+
if( data instanceof Error ){
|
2856
|
+
_this.end(0, data.message);
|
2857
|
+
}
|
2858
|
+
else{
|
2859
|
+
// Start uploading
|
2860
|
+
options.upload(options, _this);
|
2861
|
+
_this._send.call(_this, options, data);
|
2862
|
+
}
|
2762
2863
|
}, options);
|
2763
2864
|
},
|
2764
2865
|
|
2765
2866
|
_send: function (options, data){
|
2766
|
-
var _this = this, xhr, uid = _this.uid,
|
2867
|
+
var _this = this, xhr, uid = _this.uid, onLoadFnName = _this.uid + "Load", url = options.url;
|
2767
2868
|
|
2768
2869
|
api.log('XHR._send:', data);
|
2769
2870
|
|
@@ -2802,7 +2903,7 @@
|
|
2802
2903
|
_this.end(status, statusText);
|
2803
2904
|
|
2804
2905
|
api.event.off(window, 'message', onPostMessage);
|
2805
|
-
window[uid] = xhr = transport = window[
|
2906
|
+
window[uid] = xhr = transport = window[onLoadFnName] = null;
|
2806
2907
|
}
|
2807
2908
|
;
|
2808
2909
|
|
@@ -2818,7 +2919,7 @@
|
|
2818
2919
|
|
2819
2920
|
api.event.on(window, 'message', onPostMessage);
|
2820
2921
|
|
2821
|
-
window[
|
2922
|
+
window[onLoadFnName] = function (){
|
2822
2923
|
try {
|
2823
2924
|
var
|
2824
2925
|
win = transport.contentWindow
|
@@ -2833,7 +2934,7 @@
|
|
2833
2934
|
|
2834
2935
|
xhr = document.createElement('div');
|
2835
2936
|
xhr.innerHTML = '<form target="'+ uid +'" action="'+ url +'" method="POST" enctype="multipart/form-data" style="position: absolute; top: -1000px; overflow: hidden; width: 1px; height: 1px;">'
|
2836
|
-
+ '<iframe name="'+ uid +'" src="javascript:false;" onload="' +
|
2937
|
+
+ '<iframe name="'+ uid +'" src="javascript:false;" onload="window.' + onLoadFnName + ' && ' + onLoadFnName + '();"></iframe>'
|
2837
2938
|
+ (jsonp && (options.url.indexOf('=?') < 0) ? '<input value="'+ uid +'" name="'+jsonp+'" type="hidden"/>' : '')
|
2838
2939
|
+ '</form>'
|
2839
2940
|
;
|
@@ -2856,7 +2957,11 @@
|
|
2856
2957
|
|
2857
2958
|
// send
|
2858
2959
|
_this.readyState = 2; // loaded
|
2859
|
-
|
2960
|
+
try {
|
2961
|
+
form.submit();
|
2962
|
+
} catch (err) {
|
2963
|
+
api.log('iframe.error: ' + err);
|
2964
|
+
}
|
2860
2965
|
form = null;
|
2861
2966
|
}
|
2862
2967
|
else {
|
@@ -3487,7 +3592,7 @@
|
|
3487
3592
|
|
3488
3593
|
if( api.multiFlash ){
|
3489
3594
|
// check state:
|
3490
|
-
//
|
3595
|
+
// p — published
|
3491
3596
|
// i — initialization
|
3492
3597
|
// r — ready
|
3493
3598
|
if( state == 'i' || state == 'r' ){
|
@@ -3649,8 +3754,8 @@
|
|
3649
3754
|
try {
|
3650
3755
|
api.log('(js -> flash).'+name+':', data);
|
3651
3756
|
return flash.get(id.flashId || id).cmd(name, data);
|
3652
|
-
} catch (
|
3653
|
-
api.log('(js -> flash).onError:',
|
3757
|
+
} catch (err){
|
3758
|
+
api.log('(js -> flash).onError:', err.toString());
|
3654
3759
|
if( !last ){
|
3655
3760
|
// try again
|
3656
3761
|
setTimeout(function (){ flash.cmd(id, name, data, true); }, 50);
|
@@ -4125,10 +4230,8 @@
|
|
4125
4230
|
var _each = api.each,
|
4126
4231
|
_cameraQueue = [];
|
4127
4232
|
|
4128
|
-
|
4129
|
-
if (api.support.flash && (api.media && !api.support.media)) {
|
4233
|
+
if (api.support.flash && (api.media && (!api.support.media || !api.html5))) {
|
4130
4234
|
(function () {
|
4131
|
-
|
4132
4235
|
function _wrap(fn) {
|
4133
4236
|
var id = fn.wid = api.uid();
|
4134
4237
|
api.Flash._fn[id] = fn;
|
@@ -1,3 +1,3 @@
|
|
1
1
|
window.FileAPI =
|
2
|
-
debug:
|
3
|
-
staticPath: '/js/jquery.fileapi/FileAPI/'
|
2
|
+
debug: false
|
3
|
+
staticPath: '/js/jquery.fileapi/FileAPI/'
|
data/lib/fileapi/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fileapi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.2
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2015-08-29 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: railties
|
@@ -95,18 +95,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
95
95
|
- - ! '>='
|
96
96
|
- !ruby/object:Gem::Version
|
97
97
|
version: '0'
|
98
|
-
segments:
|
99
|
-
- 0
|
100
|
-
hash: -202280194601742829
|
101
98
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
102
99
|
none: false
|
103
100
|
requirements:
|
104
101
|
- - ! '>='
|
105
102
|
- !ruby/object:Gem::Version
|
106
103
|
version: '0'
|
107
|
-
segments:
|
108
|
-
- 0
|
109
|
-
hash: -202280194601742829
|
110
104
|
requirements: []
|
111
105
|
rubyforge_project:
|
112
106
|
rubygems_version: 1.8.24
|