|
329 | 329 | this._metaData.size = data.length; |
330 | 330 | } else if (data && data.base64) { |
331 | 331 | this._source = AV.Promise.as(data.base64, guessedType); |
| 332 | + } else if (data && data.blob) { |
| 333 | + this._source = AV.Promise.as(data.blob, guessedType); |
| 334 | + this._isBlob = true; |
332 | 335 | } else if (typeof(File) !== "undefined" && data instanceof File) { |
333 | 336 | this._source = readAsync(data, type); |
334 | 337 | } else if(AV._isNode && Buffer.isBuffer(data)) { |
|
499 | 502 | return request._thenRunCallbacks(options); |
500 | 503 | }, |
501 | 504 |
|
| 505 | + /** |
| 506 | + * @callback UploadProgressCallback |
| 507 | + * @param {XMLHttpRequestProgressEvent} event - The progress event with 'loaded' and 'total' attributes |
| 508 | + */ |
502 | 509 | /** |
503 | 510 | * Saves the file to the AV cloud. |
| 511 | + * @param {Object} saveOptions |
| 512 | + * @param {UploadProgressCallback} [saveOptions.onProgress] |
504 | 513 | * @param {Object} options A Backbone-style options object. |
505 | 514 | * @return {AV.Promise} Promise that is resolved when the save finishes. |
506 | 515 | */ |
507 | | - save: function(options) { |
| 516 | + save: function() { |
| 517 | + var options = null; |
| 518 | + var saveOptions = {}; |
| 519 | + if(arguments.length === 1) { |
| 520 | + options = arguments[0]; |
| 521 | + } else if(arguments.length === 2) { |
| 522 | + saveOptions = arguments[0]; |
| 523 | + options = arguments[1]; |
| 524 | + } |
508 | 525 | var self = this; |
509 | 526 | if (!self._previousSave) { |
510 | 527 | if(self._source){ |
|
524 | 541 | ACL: self._acl, |
525 | 542 | name:self._name, |
526 | 543 | mime_type: type, |
527 | | - metaData: self._metaData, |
| 544 | + metaData: self._metaData |
528 | 545 | }; |
529 | 546 | if(type && self._metaData.mime_type == null) |
530 | 547 | self._metaData.mime_type = type; |
|
553 | 570 | self.destroy(); |
554 | 571 | } |
555 | 572 | }); |
| 573 | + return promise; |
| 574 | + }); |
| 575 | + } else if (this._isBlob) { |
| 576 | + |
| 577 | + self._previousSave = self._source.then(function(blob, type) { |
| 578 | + //Create 16-bits uuid as qiniu key. |
| 579 | + var hexOctet = function() { |
| 580 | + return Math.floor((1+Math.random())*0x10000).toString(16).substring(1); |
| 581 | + }; |
| 582 | + var nameParts = self._name.split('.'); |
| 583 | + var key = hexOctet() + hexOctet() + hexOctet() + hexOctet() + hexOctet() |
| 584 | + + '.' + nameParts[nameParts.length - 1]; |
| 585 | + var data = { |
| 586 | + key: key, |
| 587 | + ACL: self._acl, |
| 588 | + name:self._name, |
| 589 | + mime_type: type, |
| 590 | + metaData: self._metaData |
| 591 | + }; |
| 592 | + if(type && self._metaData.mime_type == null) |
| 593 | + self._metaData.mime_type = type; |
| 594 | + self._qiniu_key = key; |
| 595 | + self._blob = blob; |
| 596 | + return AV._request("qiniu", null, null, 'POST', data); |
| 597 | + }).then(function(response) { |
| 598 | + self._url = response.url; |
| 599 | + self._bucket = response.bucket; |
| 600 | + self.id = response.objectId; |
| 601 | + //Get the uptoken to upload files to qiniu. |
| 602 | + var uptoken = response.token; |
| 603 | + |
| 604 | + var data = new FormData(); |
| 605 | + data.append("file", self._blob, self._name); |
| 606 | + data.append("key", self._qiniu_key); |
| 607 | + data.append("token", uptoken); |
| 608 | + |
| 609 | + var promise = new AV.Promise(); |
| 610 | + var handled = false; |
| 611 | + |
| 612 | + var xhr = new AV.XMLHttpRequest(); |
| 613 | + |
| 614 | + xhr.upload.addEventListener('progress', function(e) { |
| 615 | + if (e.lengthComputable) { |
| 616 | + saveOptions.onProgress && saveOptions.onProgress(e); |
| 617 | + } |
| 618 | + }, false); |
| 619 | + |
| 620 | + xhr.onreadystatechange = function() { |
| 621 | + if (xhr.readyState === 4) { |
| 622 | + if (handled) { |
| 623 | + return; |
| 624 | + } |
| 625 | + handled = true; |
| 626 | + |
| 627 | + delete self._qiniu_key; |
| 628 | + delete self._blob; |
| 629 | + if (xhr.status >= 200 && xhr.status < 300) { |
| 630 | + var response; |
| 631 | + try { |
| 632 | + response = JSON.parse(xhr.responseText); |
| 633 | + } catch (e) { |
| 634 | + promise.reject(e); |
| 635 | + self.destroy(); |
| 636 | + } |
| 637 | + if (response) { |
| 638 | + promise.resolve(self); |
| 639 | + } else { |
| 640 | + promise.reject(response); |
| 641 | + } |
| 642 | + } else { |
| 643 | + promise.reject(xhr); |
| 644 | + self.destroy(); |
| 645 | + } |
| 646 | + } |
| 647 | + }; |
| 648 | + xhr.open('POST', 'http://upload.qiniu.com', true); |
| 649 | + xhr.send(data); |
| 650 | + |
556 | 651 | return promise; |
557 | 652 | }); |
558 | 653 | } else { |
|
563 | 658 | _ContentType: type, |
564 | 659 | ACL: self._acl, |
565 | 660 | mime_type: type, |
566 | | - metaData: self._metaData, |
| 661 | + metaData: self._metaData |
567 | 662 | }; |
568 | 663 | return AV._request("files", self._name, null, 'POST', data); |
569 | 664 | }).then(function(response) { |
|
0 commit comments