index.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. 'use strict';
  2. /*globals Promise */
  3. var JSZipUtils = {};
  4. // just use the responseText with xhr1, response with xhr2.
  5. // The transformation doesn't throw away high-order byte (with responseText)
  6. // because JSZip handles that case. If not used with JSZip, you may need to
  7. // do it, see https://developer.mozilla.org/En/Using_XMLHttpRequest#Handling_binary_data
  8. JSZipUtils._getBinaryFromXHR = function (xhr) {
  9. // for xhr.responseText, the 0xFF mask is applied by JSZip
  10. return xhr.response || xhr.responseText;
  11. };
  12. // taken from jQuery
  13. function createStandardXHR() {
  14. try {
  15. return new window.XMLHttpRequest();
  16. } catch( e ) {}
  17. }
  18. function createActiveXHR() {
  19. try {
  20. return new window.ActiveXObject("Microsoft.XMLHTTP");
  21. } catch( e ) {}
  22. }
  23. // Create the request object
  24. var createXHR = (typeof window !== "undefined" && window.ActiveXObject) ?
  25. /* Microsoft failed to properly
  26. * implement the XMLHttpRequest in IE7 (can't request local files),
  27. * so we use the ActiveXObject when it is available
  28. * Additionally XMLHttpRequest can be disabled in IE7/IE8 so
  29. * we need a fallback.
  30. */
  31. function() {
  32. return createStandardXHR() || createActiveXHR();
  33. } :
  34. // For all other browsers, use the standard XMLHttpRequest object
  35. createStandardXHR;
  36. /**
  37. * @param {string} path The path to the resource to GET.
  38. * @param {function|{callback: function, progress: function}} options
  39. * @return {Promise|undefined} If no callback is passed then a promise is returned
  40. */
  41. JSZipUtils.getBinaryContent = function (path, options) {
  42. var promise, resolve, reject;
  43. var callback;
  44. if (!options) {
  45. options = {};
  46. }
  47. // backward compatible callback
  48. if (typeof options === "function") {
  49. callback = options;
  50. options = {};
  51. } else if (typeof options.callback === 'function') {
  52. // callback inside options object
  53. callback = options.callback;
  54. }
  55. if (!callback && typeof Promise !== "undefined") {
  56. promise = new Promise(function (_resolve, _reject) {
  57. resolve = _resolve;
  58. reject = _reject;
  59. });
  60. } else {
  61. resolve = function (data) { callback(null, data); };
  62. reject = function (err) { callback(err, null); };
  63. }
  64. /*
  65. * Here is the tricky part : getting the data.
  66. * In firefox/chrome/opera/... setting the mimeType to 'text/plain; charset=x-user-defined'
  67. * is enough, the result is in the standard xhr.responseText.
  68. * cf https://developer.mozilla.org/En/XMLHttpRequest/Using_XMLHttpRequest#Receiving_binary_data_in_older_browsers
  69. * In IE <= 9, we must use (the IE only) attribute responseBody
  70. * (for binary data, its content is different from responseText).
  71. * In IE 10, the 'charset=x-user-defined' trick doesn't work, only the
  72. * responseType will work :
  73. * http://msdn.microsoft.com/en-us/library/ie/hh673569%28v=vs.85%29.aspx#Binary_Object_upload_and_download
  74. *
  75. * I'd like to use jQuery to avoid this XHR madness, but it doesn't support
  76. * the responseType attribute : http://bugs.jquery.com/ticket/11461
  77. */
  78. try {
  79. var xhr = createXHR();
  80. xhr.open('GET', path, true);
  81. // recent browsers
  82. if ("responseType" in xhr) {
  83. xhr.responseType = "arraybuffer";
  84. }
  85. // older browser
  86. if(xhr.overrideMimeType) {
  87. xhr.overrideMimeType("text/plain; charset=x-user-defined");
  88. }
  89. xhr.onreadystatechange = function (event) {
  90. // use `xhr` and not `this`... thanks IE
  91. if (xhr.readyState === 4) {
  92. if (xhr.status === 200 || xhr.status === 0) {
  93. try {
  94. resolve(JSZipUtils._getBinaryFromXHR(xhr));
  95. } catch(err) {
  96. reject(new Error(err));
  97. }
  98. } else {
  99. reject(new Error("Ajax error for " + path + " : " + this.status + " " + this.statusText));
  100. }
  101. }
  102. };
  103. if(options.progress) {
  104. xhr.onprogress = function(e) {
  105. options.progress({
  106. path: path,
  107. originalEvent: e,
  108. percent: e.loaded / e.total * 100,
  109. loaded: e.loaded,
  110. total: e.total
  111. });
  112. };
  113. }
  114. xhr.send();
  115. } catch (e) {
  116. reject(new Error(e), null);
  117. }
  118. // returns a promise or undefined depending on whether a callback was
  119. // provided
  120. return promise;
  121. };
  122. // export
  123. module.exports = JSZipUtils;
  124. // enforcing Stuk's coding style
  125. // vim: set shiftwidth=4 softtabstop=4: